source: josm/trunk/src/org/openstreetmap/josm/data/osm/history/HistoryDataSet.java@ 12630

Last change on this file since 12630 was 12630, checked in by Don-vip, 7 years ago

see #15182 - deprecate Main.map and Main.isDisplayingMapView(). Replacements: gui.MainApplication.getMap() / gui.MainApplication.isDisplayingMapView()

  • Property svn:eol-style set to native
File size: 8.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.history;
3
4import java.text.MessageFormat;
5import java.util.ArrayList;
6import java.util.Collection;
7import java.util.HashMap;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Map;
11import java.util.Set;
12import java.util.concurrent.CopyOnWriteArrayList;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.osm.Changeset;
16import org.openstreetmap.josm.data.osm.IPrimitive;
17import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
18import org.openstreetmap.josm.data.osm.PrimitiveId;
19import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
20import org.openstreetmap.josm.gui.MainApplication;
21import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
22import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
23import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
24import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
25import org.openstreetmap.josm.tools.CheckParameterUtil;
26
27/**
28 * A data set holding histories of OSM primitives.
29 * @since 1670
30 * @since 10386 (new LayerChangeListener interface)
31 */
32public class HistoryDataSet implements LayerChangeListener {
33 /** the unique instance */
34 private static HistoryDataSet historyDataSet;
35
36 /**
37 * Replies the unique instance of the history data set
38 *
39 * @return the unique instance of the history data set
40 */
41 public static synchronized HistoryDataSet getInstance() {
42 if (historyDataSet == null) {
43 historyDataSet = new HistoryDataSet();
44 Main.getLayerManager().addLayerChangeListener(historyDataSet);
45 }
46 return historyDataSet;
47 }
48
49 /** the history data */
50 private final Map<PrimitiveId, ArrayList<HistoryOsmPrimitive>> data;
51 private final CopyOnWriteArrayList<HistoryDataSetListener> listeners;
52 private final Map<Long, Changeset> changesets;
53
54 /**
55 * Constructs a new {@code HistoryDataSet}.
56 */
57 public HistoryDataSet() {
58 data = new HashMap<>();
59 listeners = new CopyOnWriteArrayList<>();
60 changesets = new HashMap<>();
61 }
62
63 /**
64 * Adds a listener that listens to history data set events.
65 * @param listener The listener
66 */
67 public void addHistoryDataSetListener(HistoryDataSetListener listener) {
68 if (listener != null) {
69 listeners.addIfAbsent(listener);
70 }
71 }
72
73 /**
74 * Removes a listener that listens to history data set events.
75 * @param listener The listener
76 */
77 public void removeHistoryDataSetListener(HistoryDataSetListener listener) {
78 listeners.remove(listener);
79 }
80
81 protected void fireHistoryUpdated(PrimitiveId id) {
82 for (HistoryDataSetListener l : listeners) {
83 l.historyUpdated(this, id);
84 }
85 }
86
87 protected void fireCacheCleared() {
88 for (HistoryDataSetListener l : listeners) {
89 l.historyDataSetCleared(this);
90 }
91 }
92
93 /**
94 * Replies the history primitive for the primitive with id <code>id</code>
95 * and version <code>version</code>. null, if no such primitive exists.
96 *
97 * @param id the id of the primitive. &gt; 0 required.
98 * @param type the primitive type. Must not be null.
99 * @param version the version of the primitive. &gt; 0 required
100 * @return the history primitive for the primitive with id <code>id</code>,
101 * type <code>type</code>, and version <code>version</code>
102 */
103 public HistoryOsmPrimitive get(long id, OsmPrimitiveType type, long version) {
104 if (id <= 0)
105 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected, got {1}", "id", id));
106 CheckParameterUtil.ensureParameterNotNull(type, "type");
107 if (version <= 0)
108 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected, got {1}", "version", version));
109
110 SimplePrimitiveId pid = new SimplePrimitiveId(id, type);
111 List<HistoryOsmPrimitive> versions = data.get(pid);
112 if (versions == null)
113 return null;
114 for (HistoryOsmPrimitive primitive: versions) {
115 if (primitive.matches(id, version))
116 return primitive;
117 }
118 return null;
119 }
120
121 /**
122 * Adds a history primitive to the data set
123 *
124 * @param primitive the history primitive to add
125 */
126 public void put(HistoryOsmPrimitive primitive) {
127 PrimitiveId id = new SimplePrimitiveId(primitive.getId(), primitive.getType());
128 if (data.get(id) == null) {
129 data.put(id, new ArrayList<HistoryOsmPrimitive>());
130 }
131 data.get(id).add(primitive);
132 fireHistoryUpdated(id);
133 }
134
135 /**
136 * Adds a changeset to the data set
137 *
138 * @param changeset the changeset to add
139 */
140 public void putChangeset(Changeset changeset) {
141 changesets.put((long) changeset.getId(), changeset);
142 fireHistoryUpdated(null);
143 }
144
145 /**
146 * Replies the history for a given primitive with id <code>id</code>
147 * and type <code>type</code>.
148 *
149 * @param id the id the if of the primitive. &gt; 0 required
150 * @param type the type of the primitive. Must not be null.
151 * @return the history. null, if there isn't a history for <code>id</code> and
152 * <code>type</code>.
153 * @throws IllegalArgumentException if id &lt;= 0
154 * @throws IllegalArgumentException if type is null
155 */
156 public History getHistory(long id, OsmPrimitiveType type) {
157 if (id <= 0)
158 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected, got {1}", "id", id));
159 CheckParameterUtil.ensureParameterNotNull(type, "type");
160 SimplePrimitiveId pid = new SimplePrimitiveId(id, type);
161 return getHistory(pid);
162 }
163
164 /**
165 * Replies the history for a primitive with id <code>id</code>. null, if no
166 * such history exists.
167 *
168 * @param pid the primitive id. Must not be null.
169 * @return the history for a primitive with id <code>id</code>. null, if no
170 * such history exists
171 * @throws IllegalArgumentException if pid is null
172 */
173 public History getHistory(PrimitiveId pid) {
174 CheckParameterUtil.ensureParameterNotNull(pid, "pid");
175 List<HistoryOsmPrimitive> versions = data.get(pid);
176 if (versions == null && pid instanceof IPrimitive) {
177 versions = data.get(((IPrimitive) pid).getPrimitiveId());
178 }
179 if (versions == null)
180 return null;
181 for (HistoryOsmPrimitive i : versions) {
182 i.setChangeset(changesets.get(i.getChangesetId()));
183 }
184 return new History(pid.getUniqueId(), pid.getType(), versions);
185 }
186
187 /**
188 * merges the histories from the {@link HistoryDataSet} other in this history data set
189 *
190 * @param other the other history data set. Ignored if null.
191 */
192 public void mergeInto(HistoryDataSet other) {
193 if (other == null)
194 return;
195 this.data.putAll(other.data);
196 this.changesets.putAll(other.changesets);
197 fireHistoryUpdated(null);
198 }
199
200 /**
201 * Gets a unsorted set of all changeset ids that were used by the primitives in this data set
202 * @return The ids
203 */
204 public Collection<Long> getChangesetIds() {
205 final Set<Long> ids = new HashSet<>();
206 for (Collection<HistoryOsmPrimitive> i : data.values()) {
207 for (HistoryOsmPrimitive j : i) {
208 ids.add(j.getChangesetId());
209 }
210 }
211 return ids;
212 }
213
214 /* ------------------------------------------------------------------------------ */
215 /* interface LayerChangeListener */
216 /* ------------------------------------------------------------------------------ */
217 @Override
218 public void layerOrderChanged(LayerOrderChangeEvent e) {
219 /* irrelevant in this context */
220 }
221
222 @Override
223 public void layerAdded(LayerAddEvent e) {
224 /* irrelevant in this context */
225 }
226
227 @Override
228 public void layerRemoving(LayerRemoveEvent e) {
229 if (!MainApplication.isDisplayingMapView()) return;
230 if (Main.getLayerManager().getLayers().isEmpty()) {
231 data.clear();
232 fireCacheCleared();
233 }
234 }
235}
Note: See TracBrowser for help on using the repository browser.