001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.HashMap; 005import java.util.HashSet; 006import java.util.Iterator; 007import java.util.Map; 008import java.util.Map.Entry; 009import java.util.Set; 010 011import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; 012import org.openstreetmap.josm.tools.CheckParameterUtil; 013 014/** 015 * A ChangesetDataSet holds the content of a changeset. 016 */ 017public class ChangesetDataSet { 018 019 public enum ChangesetModificationType { 020 CREATED, 021 UPDATED, 022 DELETED 023 } 024 025 public interface ChangesetDataSetEntry { 026 ChangesetModificationType getModificationType(); 027 028 HistoryOsmPrimitive getPrimitive(); 029 } 030 031 private final Map<PrimitiveId, HistoryOsmPrimitive> primitives = new HashMap<>(); 032 private final Map<PrimitiveId, ChangesetModificationType> modificationTypes = new HashMap<>(); 033 034 /** 035 * Remembers a history primitive with the given modification type 036 * 037 * @param primitive the primitive. Must not be null. 038 * @param cmt the modification type. Must not be null. 039 * @throws IllegalArgumentException if primitive is null 040 * @throws IllegalArgumentException if cmt is null 041 */ 042 public void put(HistoryOsmPrimitive primitive, ChangesetModificationType cmt) { 043 CheckParameterUtil.ensureParameterNotNull(primitive, "primitive"); 044 CheckParameterUtil.ensureParameterNotNull(cmt, "cmt"); 045 primitives.put(primitive.getPrimitiveId(), primitive); 046 modificationTypes.put(primitive.getPrimitiveId(), cmt); 047 } 048 049 /** 050 * Replies true if the changeset content contains the object with primitive <code>id</code>. 051 * @param id the id. 052 * @return true if the changeset content contains the object with primitive <code>id</code> 053 */ 054 public boolean contains(PrimitiveId id) { 055 if (id == null) return false; 056 return primitives.containsKey(id); 057 } 058 059 /** 060 * Replies the modification type for the object with id <code>id</code>. Replies null, if id is null or 061 * if the object with id <code>id</code> isn't in the changeset content. 062 * 063 * @param id the id 064 * @return the modification type 065 */ 066 public ChangesetModificationType getModificationType(PrimitiveId id) { 067 if (!contains(id)) return null; 068 return modificationTypes.get(id); 069 } 070 071 /** 072 * Replies true if the primitive with id <code>id</code> was created in this 073 * changeset. Replies false, if id is null. 074 * 075 * @param id the id 076 * @return true if the primitive with id <code>id</code> was created in this 077 * changeset. 078 */ 079 public boolean isCreated(PrimitiveId id) { 080 if (!contains(id)) return false; 081 return ChangesetModificationType.CREATED.equals(getModificationType(id)); 082 } 083 084 /** 085 * Replies true if the primitive with id <code>id</code> was updated in this 086 * changeset. Replies false, if id is null. 087 * 088 * @param id the id 089 * @return true if the primitive with id <code>id</code> was updated in this 090 * changeset. 091 */ 092 public boolean isUpdated(PrimitiveId id) { 093 if (!contains(id)) return false; 094 return ChangesetModificationType.UPDATED.equals(getModificationType(id)); 095 } 096 097 /** 098 * Replies true if the primitive with id <code>id</code> was deleted in this 099 * changeset. Replies false, if id is null. 100 * 101 * @param id the id 102 * @return true if the primitive with id <code>id</code> was deleted in this 103 * changeset. 104 */ 105 public boolean isDeleted(PrimitiveId id) { 106 if (!contains(id)) return false; 107 return ChangesetModificationType.DELETED.equals(getModificationType(id)); 108 } 109 110 /** 111 * Replies the set of primitives with a specific modification type 112 * 113 * @param cmt the modification type. Must not be null. 114 * @return the set of primitives 115 * @throws IllegalArgumentException if cmt is null 116 */ 117 public Set<HistoryOsmPrimitive> getPrimitivesByModificationType(ChangesetModificationType cmt) { 118 CheckParameterUtil.ensureParameterNotNull(cmt, "cmt"); 119 Set<HistoryOsmPrimitive> ret = new HashSet<>(); 120 for (Entry<PrimitiveId, ChangesetModificationType> entry: modificationTypes.entrySet()) { 121 if (entry.getValue().equals(cmt)) { 122 ret.add(primitives.get(entry.getKey())); 123 } 124 } 125 return ret; 126 } 127 128 /** 129 * Replies the number of objects in the dataset 130 * 131 * @return the number of objects in the dataset 132 */ 133 public int size() { 134 return primitives.size(); 135 } 136 137 /** 138 * Replies the {@link HistoryOsmPrimitive} with id <code>id</code> from this 139 * dataset. null, if there is no such primitive in the data set. 140 * 141 * @param id the id 142 * @return the {@link HistoryOsmPrimitive} with id <code>id</code> from this 143 * dataset 144 */ 145 public HistoryOsmPrimitive getPrimitive(PrimitiveId id) { 146 if (id == null) return null; 147 return primitives.get(id); 148 } 149 150 public Iterator<ChangesetDataSetEntry> iterator() { 151 return new DefaultIterator(); 152 } 153 154 private static class DefaultChangesetDataSetEntry implements ChangesetDataSetEntry { 155 private final ChangesetModificationType modificationType; 156 private final HistoryOsmPrimitive primitive; 157 158 DefaultChangesetDataSetEntry(ChangesetModificationType modificationType, HistoryOsmPrimitive primitive) { 159 this.modificationType = modificationType; 160 this.primitive = primitive; 161 } 162 163 @Override 164 public ChangesetModificationType getModificationType() { 165 return modificationType; 166 } 167 168 @Override 169 public HistoryOsmPrimitive getPrimitive() { 170 return primitive; 171 } 172 } 173 174 private class DefaultIterator implements Iterator<ChangesetDataSetEntry> { 175 private final Iterator<Entry<PrimitiveId, ChangesetModificationType>> typeIterator; 176 177 DefaultIterator() { 178 typeIterator = modificationTypes.entrySet().iterator(); 179 } 180 181 @Override 182 public boolean hasNext() { 183 return typeIterator.hasNext(); 184 } 185 186 @Override 187 public ChangesetDataSetEntry next() { 188 Entry<PrimitiveId, ChangesetModificationType> next = typeIterator.next(); 189 ChangesetModificationType type = next.getValue(); 190 HistoryOsmPrimitive primitive = primitives.get(next.getKey()); 191 return new DefaultChangesetDataSetEntry(type, primitive); 192 } 193 194 @Override 195 public void remove() { 196 throw new UnsupportedOperationException(); 197 } 198 } 199}