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

Last change on this file since 2448 was 2448, checked in by Gubaer, 14 years ago

fixed #3352: History doesn't get invalidated on upload?
fixed #3912: Extend history dialog to contain the currently modified version
new: zoom to node in list of nodes in history dialog (popup menu)
new: load history of node from node list in history dialog (popup menu or double click)
fixed: close all history dialogs when the number of layers drop to 0
fixed: implemented equals() and hashCode() on SimplePrimitiveId
fixed: history features now usePrimitiveId instead of long.

File size: 7.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.history;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.ArrayList;
7import java.util.Collections;
8import java.util.Comparator;
9import java.util.Date;
10import java.util.List;
11
12import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
13import org.openstreetmap.josm.data.osm.PrimitiveId;
14import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
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 *
20 */
21public class History{
22 private static interface FilterPredicate {
23 boolean matches(HistoryOsmPrimitive primitive);
24 }
25
26 private static History filter(History history, FilterPredicate predicate) {
27 ArrayList<HistoryOsmPrimitive> out = new ArrayList<HistoryOsmPrimitive>();
28 for (HistoryOsmPrimitive primitive: history.versions) {
29 if (predicate.matches(primitive)) {
30 out.add(primitive);
31 }
32 }
33 return new History(history.id, history.type,out);
34 }
35
36 /** the list of object snapshots */
37 private ArrayList<HistoryOsmPrimitive> versions;
38 /** the object id */
39 private long id;
40 private OsmPrimitiveType type;
41
42 /**
43 * Creates a new history for an OSM primitive
44 *
45 * @param id the id. >0 required.
46 * @param type the primitive type. Must not be null.
47 * @param versions a list of versions. Can be null.
48 * @throws IllegalArgumentException thrown if id <= 0
49 * @throws IllegalArgumentException if type is null
50 *
51 */
52 protected History(long id, OsmPrimitiveType type, List<HistoryOsmPrimitive> versions) {
53 if (id <= 0)
54 throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected, got {1}", "id", id));
55 if (type == null)
56 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type"));
57 this.id = id;
58 this.type = type;
59 this.versions = new ArrayList<HistoryOsmPrimitive>();
60 if (versions != null) {
61 this.versions.addAll(versions);
62 }
63 }
64
65 public History sortAscending() {
66 ArrayList<HistoryOsmPrimitive> copy = new ArrayList<HistoryOsmPrimitive>(versions);
67 Collections.sort(
68 copy,
69 new Comparator<HistoryOsmPrimitive>() {
70 public int compare(HistoryOsmPrimitive o1, HistoryOsmPrimitive o2) {
71 return o1.compareTo(o2);
72 }
73 }
74 );
75 return new History(id, type, copy);
76 }
77
78 public History sortDescending() {
79 ArrayList<HistoryOsmPrimitive> copy = new ArrayList<HistoryOsmPrimitive>(versions);
80 Collections.sort(
81 copy,
82 new Comparator<HistoryOsmPrimitive>() {
83 public int compare(HistoryOsmPrimitive o1, HistoryOsmPrimitive o2) {
84 return o2.compareTo(o1);
85 }
86 }
87 );
88 return new History(id, type,copy);
89 }
90
91 public History from(final Date fromDate) {
92 return filter(
93 this,
94 new FilterPredicate() {
95 public boolean matches(HistoryOsmPrimitive primitive) {
96 return primitive.getTimestamp().compareTo(fromDate) >= 0;
97 }
98 }
99 );
100 }
101
102 public History until(final Date untilDate) {
103 return filter(
104 this,
105 new FilterPredicate() {
106 public boolean matches(HistoryOsmPrimitive primitive) {
107 return primitive.getTimestamp().compareTo(untilDate) <= 0;
108 }
109 }
110 );
111 }
112
113 public History between(Date fromDate, Date untilDate) {
114 return this.from(fromDate).until(untilDate);
115 }
116
117 public History from(final long fromVersion) {
118 return filter(
119 this,
120 new FilterPredicate() {
121 public boolean matches(HistoryOsmPrimitive primitive) {
122 return primitive.getVersion() >= fromVersion;
123 }
124 }
125 );
126 }
127
128 public History until(final long untilVersion) {
129 return filter(
130 this,
131 new FilterPredicate() {
132 public boolean matches(HistoryOsmPrimitive primitive) {
133 return primitive.getVersion() <= untilVersion;
134 }
135 }
136 );
137 }
138
139 public History between(long fromVersion, long untilVersion) {
140 return this.from(fromVersion).until(untilVersion);
141 }
142
143 public History forUser(final String user) {
144 return filter(
145 this,
146 new FilterPredicate() {
147 public boolean matches(HistoryOsmPrimitive primitive) {
148 return primitive.getUser().equals(user);
149 }
150 }
151 );
152 }
153
154 public History forUserId(final long uid) {
155 return filter(
156 this,
157 new FilterPredicate() {
158 public boolean matches(HistoryOsmPrimitive primitive) {
159 return primitive.getUid() == uid;
160 }
161 }
162 );
163 }
164
165 public long getId() {
166 return id;
167 }
168
169 /**
170 * Replies the primitive id for this history.
171 *
172 * @return the primitive id
173 */
174 public PrimitiveId getPrimitmiveId() {
175 return new SimplePrimitiveId(id, type);
176 }
177
178 public boolean contains(long version){
179 for (HistoryOsmPrimitive primitive: versions) {
180 if (primitive.matches(id,version))
181 return true;
182 }
183 return false;
184 }
185
186 /**
187 * Replies the history primitive with version <code>version</code>. null,
188 * if no such primitive exists.
189 *
190 * @param version the version
191 * @return the history primitive with version <code>version</code>
192 */
193 public HistoryOsmPrimitive getByVersion(long version) {
194 for (HistoryOsmPrimitive primitive: versions) {
195 if (primitive.matches(id,version))
196 return primitive;
197 }
198 return null;
199 }
200
201 public HistoryOsmPrimitive getByDate(Date date) {
202 History h = sortAscending();
203
204 if (h.versions.isEmpty())
205 return null;
206 if (h.get(0).getTimestamp().compareTo(date)> 0)
207 return null;
208 for (int i = 1; i < h.versions.size();i++) {
209 if (h.get(i-1).getTimestamp().compareTo(date) <= 0
210 && h.get(i).getTimestamp().compareTo(date) >= 0)
211 return h.get(i);
212 }
213 return h.getLatest();
214 }
215
216 public HistoryOsmPrimitive get(int idx) {
217 if (idx < 0 || idx >= versions.size())
218 throw new IndexOutOfBoundsException(tr("Parameter ''{0}'' in range 0..{1} expected. Got ''{2}''.", "idx", versions.size()-1, idx));
219 return versions.get(idx);
220 }
221
222 public HistoryOsmPrimitive getEarliest() {
223 if (isEmpty())
224 return null;
225 return sortAscending().versions.get(0);
226 }
227
228 public HistoryOsmPrimitive getLatest() {
229 if (isEmpty())
230 return null;
231 return sortDescending().versions.get(0);
232 }
233
234 public int getNumVersions() {
235 return versions.size();
236 }
237
238 public boolean isEmpty() {
239 return versions.isEmpty();
240 }
241
242 public OsmPrimitiveType getType() {
243 return type;
244 }
245}
Note: See TracBrowser for help on using the repository browser.