source: josm/trunk/src/org/openstreetmap/josm/data/osm/history/History.java@ 8512

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

checkstyle: redundant modifiers

  • Property svn:eol-style set to native
File size: 11.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.Collections;
7import java.util.Comparator;
8import java.util.Date;
9import java.util.List;
10
11import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
12import org.openstreetmap.josm.data.osm.PrimitiveId;
13import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
14import org.openstreetmap.josm.tools.CheckParameterUtil;
15
16/**
17 * Represents the history of an OSM primitive. The history consists
18 * of a list of object snapshots with a specific version.
19 * @since 1670
20 */
21public class History {
22
23 private interface FilterPredicate {
24 boolean matches(HistoryOsmPrimitive primitive);
25 }
26
27 private static History filter(History history, FilterPredicate predicate) {
28 List<HistoryOsmPrimitive> out = new ArrayList<>();
29 for (HistoryOsmPrimitive primitive: history.versions) {
30 if (predicate.matches(primitive)) {
31 out.add(primitive);
32 }
33 }
34 return new History(history.id, history.type, out);
35 }
36
37 /** the list of object snapshots */
38 private List<HistoryOsmPrimitive> versions;
39 /** the object id */
40 private final long id;
41 /** the object type */
42 private final OsmPrimitiveType type;
43
44 /**
45 * Creates a new history for an OSM primitive.
46 *
47 * @param id the id. &gt; 0 required.
48 * @param type the primitive type. Must not be null.
49 * @param versions a list of versions. Can be null.
50 * @throws IllegalArgumentException if id &lt;= 0
51 * @throws IllegalArgumentException if type is null
52 */
53 protected History(long id, OsmPrimitiveType type, List<HistoryOsmPrimitive> versions) {
54 if (id <= 0)
55 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected, got {1}", "id", id));
56 CheckParameterUtil.ensureParameterNotNull(type, "type");
57 this.id = id;
58 this.type = type;
59 this.versions = new ArrayList<>();
60 if (versions != null) {
61 this.versions.addAll(versions);
62 }
63 }
64
65 /**
66 * Returns a new copy of this history, sorted in ascending order.
67 * @return a new copy of this history, sorted in ascending order
68 */
69 public History sortAscending() {
70 List<HistoryOsmPrimitive> copy = new ArrayList<>(versions);
71 Collections.sort(
72 copy,
73 new Comparator<HistoryOsmPrimitive>() {
74 @Override
75 public int compare(HistoryOsmPrimitive o1, HistoryOsmPrimitive o2) {
76 return o1.compareTo(o2);
77 }
78 }
79 );
80 return new History(id, type, copy);
81 }
82
83 /**
84 * Returns a new copy of this history, sorted in descending order.
85 * @return a new copy of this history, sorted in descending order
86 */
87 public History sortDescending() {
88 List<HistoryOsmPrimitive> copy = new ArrayList<>(versions);
89 Collections.sort(
90 copy,
91 new Comparator<HistoryOsmPrimitive>() {
92 @Override
93 public int compare(HistoryOsmPrimitive o1, HistoryOsmPrimitive o2) {
94 return o2.compareTo(o1);
95 }
96 }
97 );
98 return new History(id, type, copy);
99 }
100
101 /**
102 * Returns a new partial copy of this history, from the given date
103 * @param fromDate the starting date
104 * @return a new partial copy of this history, from the given date
105 */
106 public History from(final Date fromDate) {
107 return filter(
108 this,
109 new FilterPredicate() {
110 @Override
111 public boolean matches(HistoryOsmPrimitive primitive) {
112 return primitive.getTimestamp().compareTo(fromDate) >= 0;
113 }
114 }
115 );
116 }
117
118 /**
119 * Returns a new partial copy of this history, until the given date
120 * @param untilDate the end date
121 * @return a new partial copy of this history, until the given date
122 */
123 public History until(final Date untilDate) {
124 return filter(
125 this,
126 new FilterPredicate() {
127 @Override
128 public boolean matches(HistoryOsmPrimitive primitive) {
129 return primitive.getTimestamp().compareTo(untilDate) <= 0;
130 }
131 }
132 );
133 }
134
135 /**
136 * Returns a new partial copy of this history, between the given dates
137 * @param fromDate the starting date
138 * @param untilDate the end date
139 * @return a new partial copy of this history, between the given dates
140 */
141 public History between(Date fromDate, Date untilDate) {
142 return this.from(fromDate).until(untilDate);
143 }
144
145 /**
146 * Returns a new partial copy of this history, from the given version number
147 * @param fromVersion the starting version number
148 * @return a new partial copy of this history, from the given version number
149 */
150 public History from(final long fromVersion) {
151 return filter(
152 this,
153 new FilterPredicate() {
154 @Override
155 public boolean matches(HistoryOsmPrimitive primitive) {
156 return primitive.getVersion() >= fromVersion;
157 }
158 }
159 );
160 }
161
162 /**
163 * Returns a new partial copy of this history, to the given version number
164 * @param untilVersion the ending version number
165 * @return a new partial copy of this history, to the given version number
166 */
167 public History until(final long untilVersion) {
168 return filter(
169 this,
170 new FilterPredicate() {
171 @Override
172 public boolean matches(HistoryOsmPrimitive primitive) {
173 return primitive.getVersion() <= untilVersion;
174 }
175 }
176 );
177 }
178
179 /**
180 * Returns a new partial copy of this history, betwwen the given version numbers
181 * @param fromVersion the starting version number
182 * @param untilVersion the ending version number
183 * @return a new partial copy of this history, between the given version numbers
184 */
185 public History between(long fromVersion, long untilVersion) {
186 return this.from(fromVersion).until(untilVersion);
187 }
188
189 /**
190 * Returns a new partial copy of this history, for the given user id
191 * @param uid the user id
192 * @return a new partial copy of this history, for the given user id
193 */
194 public History forUserId(final long uid) {
195 return filter(
196 this,
197 new FilterPredicate() {
198 @Override
199 public boolean matches(HistoryOsmPrimitive primitive) {
200 return primitive.getUser() != null && primitive.getUser().getId() == uid;
201 }
202 }
203 );
204 }
205
206 /**
207 * Replies the primitive id for this history.
208 *
209 * @return the primitive id
210 * @see #getPrimitiveId
211 * @see #getType
212 */
213 public long getId() {
214 return id;
215 }
216
217 /**
218 * Replies the primitive id for this history.
219 *
220 * @return the primitive id
221 * @see #getId
222 */
223 public PrimitiveId getPrimitiveId() {
224 return new SimplePrimitiveId(id, type);
225 }
226
227 /**
228 * Determines if this history contains a specific version number.
229 * @param version the version number to look for
230 * @return {@code true} if this history contains {@code version}, {@code false} otherwise
231 */
232 public boolean contains(long version) {
233 for (HistoryOsmPrimitive primitive: versions) {
234 if (primitive.matches(id, version))
235 return true;
236 }
237 return false;
238 }
239
240 /**
241 * Replies the history primitive with version <code>version</code>. null,
242 * if no such primitive exists.
243 *
244 * @param version the version
245 * @return the history primitive with version <code>version</code>
246 */
247 public HistoryOsmPrimitive getByVersion(long version) {
248 for (HistoryOsmPrimitive primitive: versions) {
249 if (primitive.matches(id, version))
250 return primitive;
251 }
252 return null;
253 }
254
255 /**
256 * Replies the history primitive at given <code>date</code>. null,
257 * if no such primitive exists.
258 *
259 * @param date the date
260 * @return the history primitive at given <code>date</code>
261 */
262 public HistoryOsmPrimitive getByDate(Date date) {
263 History h = sortAscending();
264
265 if (h.versions.isEmpty())
266 return null;
267 if (h.get(0).getTimestamp().compareTo(date) > 0)
268 return null;
269 for (int i = 1; i < h.versions.size(); i++) {
270 if (h.get(i-1).getTimestamp().compareTo(date) <= 0
271 && h.get(i).getTimestamp().compareTo(date) >= 0)
272 return h.get(i);
273 }
274 return h.getLatest();
275 }
276
277 /**
278 * Replies the history primitive at index <code>idx</code>.
279 *
280 * @param idx the index
281 * @return the history primitive at index <code>idx</code>
282 * @throws IndexOutOfBoundsException if index out or range
283 */
284 public HistoryOsmPrimitive get(int idx) throws IndexOutOfBoundsException {
285 if (idx < 0 || idx >= versions.size())
286 throw new IndexOutOfBoundsException(MessageFormat.format(
287 "Parameter ''{0}'' in range 0..{1} expected. Got ''{2}''.", "idx", versions.size()-1, idx));
288 return versions.get(idx);
289 }
290
291 /**
292 * Replies the earliest entry of this history.
293 * @return the earliest entry of this history
294 */
295 public HistoryOsmPrimitive getEarliest() {
296 if (isEmpty())
297 return null;
298 return sortAscending().versions.get(0);
299 }
300
301 /**
302 * Replies the latest entry of this history.
303 * @return the latest entry of this history
304 */
305 public HistoryOsmPrimitive getLatest() {
306 if (isEmpty())
307 return null;
308 return sortDescending().versions.get(0);
309 }
310
311 /**
312 * Replies the number of versions.
313 * @return the number of versions
314 */
315 public int getNumVersions() {
316 return versions.size();
317 }
318
319 /**
320 * Returns true if this history contains no version.
321 * @return {@code true} if this history contains no version, {@code false} otherwise
322 */
323 public final boolean isEmpty() {
324 return versions.isEmpty();
325 }
326
327 /**
328 * Replies the primitive type for this history.
329 * @return the primitive type
330 * @see #getId
331 */
332 public OsmPrimitiveType getType() {
333 return type;
334 }
335
336 @Override
337 public String toString() {
338 StringBuilder result = new StringBuilder("History ["
339 + (type != null ? "type=" + type + ", " : "") + "id=" + id);
340 if (versions != null) {
341 result.append(", versions=\n");
342 for (HistoryOsmPrimitive v : versions) {
343 result.append('\t').append(v).append(",\n");
344 }
345 }
346 result.append(']');
347 return result.toString();
348 }
349}
Note: See TracBrowser for help on using the repository browser.