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

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

see #15182 - deprecate Main.getLayerManager(). Replacement: gui.MainApplication.getLayerManager()

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