source: josm/trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java@ 14675

Last change on this file since 14675 was 14273, checked in by stoecker, 6 years ago

fix typos - patch by naoliv - fix #16781 - Thanks a lot

  • Property svn:eol-style set to native
File size: 26.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.HashSet;
7import java.util.Set;
8
9import javax.swing.JTable;
10import javax.swing.table.TableModel;
11
12import org.openstreetmap.josm.data.UserIdentityManager;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
17import org.openstreetmap.josm.data.osm.Relation;
18import org.openstreetmap.josm.data.osm.RelationMember;
19import org.openstreetmap.josm.data.osm.RelationMemberData;
20import org.openstreetmap.josm.data.osm.User;
21import org.openstreetmap.josm.data.osm.UserInfo;
22import org.openstreetmap.josm.data.osm.Way;
23import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
24import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
25import org.openstreetmap.josm.data.osm.event.DataSetListener;
26import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
27import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
28import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
29import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
30import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
31import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
32import org.openstreetmap.josm.data.osm.history.History;
33import org.openstreetmap.josm.data.osm.history.HistoryNode;
34import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
35import org.openstreetmap.josm.data.osm.history.HistoryRelation;
36import org.openstreetmap.josm.data.osm.history.HistoryWay;
37import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor;
38import org.openstreetmap.josm.gui.MainApplication;
39import org.openstreetmap.josm.gui.layer.Layer;
40import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
41import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
42import org.openstreetmap.josm.gui.layer.OsmDataLayer;
43import org.openstreetmap.josm.gui.util.ChangeNotifier;
44import org.openstreetmap.josm.tools.CheckParameterUtil;
45import org.openstreetmap.josm.tools.Logging;
46
47/**
48 * This is the model used by the history browser.
49 *
50 * The model state consists of the following elements:
51 * <ul>
52 * <li>the {@link History} of a specific {@link OsmPrimitive}</li>
53 * <li>a dedicated version in this {@link History} called the {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
54 * <li>another version in this {@link History} called the {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
55 * </ul>
56 * {@link HistoryBrowser} always compares the {@link PointInTimeType#REFERENCE_POINT_IN_TIME} with the
57 * {@link PointInTimeType#CURRENT_POINT_IN_TIME}.
58
59 * This model provides various {@link TableModel}s for {@link JTable}s used in {@link HistoryBrowser}, for
60 * instance:
61 * <ul>
62 * <li>{@link #getTagTableModel(PointInTimeType)} replies a {@link TableModel} for the tags of either of
63 * the two selected versions</li>
64 * <li>{@link #getNodeListTableModel(PointInTimeType)} replies a {@link TableModel} for the list of nodes of
65 * the two selected versions (if the current history provides information about a {@link Way}</li>
66 * <li> {@link #getRelationMemberTableModel(PointInTimeType)} replies a {@link TableModel} for the list of relation
67 * members of the two selected versions (if the current history provides information about a {@link Relation}</li>
68 * </ul>
69 *
70 * @see HistoryBrowser
71 */
72public class HistoryBrowserModel extends ChangeNotifier implements ActiveLayerChangeListener, DataSetListener {
73 /** the history of an OsmPrimitive */
74 private History history;
75 private HistoryOsmPrimitive reference;
76 private HistoryOsmPrimitive current;
77 /**
78 * latest isn't a reference of history. It's a clone of the currently edited
79 * {@link OsmPrimitive} in the current edit layer.
80 */
81 private HistoryOsmPrimitive latest;
82
83 private final VersionTableModel versionTableModel;
84 private final TagTableModel currentTagTableModel;
85 private final TagTableModel referenceTagTableModel;
86 private final DiffTableModel currentRelationMemberTableModel;
87 private final DiffTableModel referenceRelationMemberTableModel;
88 private final DiffTableModel referenceNodeListTableModel;
89 private final DiffTableModel currentNodeListTableModel;
90
91 /**
92 * constructor
93 */
94 public HistoryBrowserModel() {
95 versionTableModel = new VersionTableModel(this);
96 currentTagTableModel = new TagTableModel(this, PointInTimeType.CURRENT_POINT_IN_TIME);
97 referenceTagTableModel = new TagTableModel(this, PointInTimeType.REFERENCE_POINT_IN_TIME);
98 referenceNodeListTableModel = new DiffTableModel();
99 currentNodeListTableModel = new DiffTableModel();
100 currentRelationMemberTableModel = new DiffTableModel();
101 referenceRelationMemberTableModel = new DiffTableModel();
102
103 DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
104 if (ds != null) {
105 ds.addDataSetListener(this);
106 }
107 MainApplication.getLayerManager().addActiveLayerChangeListener(this);
108 }
109
110 /**
111 * Creates a new history browser model for a given history.
112 *
113 * @param history the history. Must not be null.
114 * @throws IllegalArgumentException if history is null
115 */
116 public HistoryBrowserModel(History history) {
117 this();
118 CheckParameterUtil.ensureParameterNotNull(history, "history");
119 setHistory(history);
120 }
121
122 /**
123 * replies the history managed by this model
124 * @return the history
125 */
126 public History getHistory() {
127 return history;
128 }
129
130 private boolean canShowAsLatest(OsmPrimitive primitive) {
131 if (primitive == null)
132 return false;
133 if (primitive.isNew() || !primitive.isUsable())
134 return false;
135
136 //try creating a history primitive. if that fails, the primitive cannot be used.
137 try {
138 HistoryOsmPrimitive.forOsmPrimitive(primitive);
139 } catch (IllegalArgumentException ign) {
140 Logging.trace(ign);
141 return false;
142 }
143
144 if (history == null)
145 return false;
146 // only show latest of the same version if it is modified
147 if (history.getByVersion(primitive.getVersion()) != null)
148 return primitive.isModified();
149
150 // if latest version from history is higher than a non existing primitive version,
151 // that means this version has been redacted and the primitive cannot be used.
152 return history.getLatest().getVersion() <= primitive.getVersion();
153
154 // latest has a higher version than one of the primitives
155 // in the history (probably because the history got out of sync
156 // with uploaded data) -> show the primitive as latest
157 }
158
159 /**
160 * sets the history to be managed by this model
161 *
162 * @param history the history
163 *
164 */
165 public void setHistory(History history) {
166 this.history = history;
167 if (history.getNumVersions() > 0) {
168 HistoryOsmPrimitive newLatest = null;
169 DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
170 if (ds != null) {
171 OsmPrimitive p = ds.getPrimitiveById(history.getId(), history.getType());
172 if (canShowAsLatest(p)) {
173 newLatest = new HistoryPrimitiveBuilder().build(p);
174 }
175 }
176 if (newLatest == null) {
177 current = history.getLatest();
178 int prevIndex = history.getNumVersions() - 2;
179 reference = prevIndex < 0 ? history.getEarliest() : history.get(prevIndex);
180 } else {
181 reference = history.getLatest();
182 current = newLatest;
183 }
184 setLatest(newLatest);
185 }
186 initTagTableModels();
187 fireModelChange();
188 }
189
190 private void fireModelChange() {
191 initNodeListTableModels();
192 initMemberListTableModels();
193 fireStateChanged();
194 versionTableModel.fireTableDataChanged();
195 }
196
197 /**
198 * Replies the table model to be used in a {@link JTable} which
199 * shows the list of versions in this history.
200 *
201 * @return the table model
202 */
203 public VersionTableModel getVersionTableModel() {
204 return versionTableModel;
205 }
206
207 private void initTagTableModels() {
208 currentTagTableModel.initKeyList();
209 referenceTagTableModel.initKeyList();
210 }
211
212 /**
213 * Should be called every time either reference of current changes to update the diff.
214 * TODO: Maybe rename to reflect this? eg. updateNodeListTableModels
215 */
216 private void initNodeListTableModels() {
217 if (current == null || current.getType() != OsmPrimitiveType.WAY
218 || reference == null || reference.getType() != OsmPrimitiveType.WAY)
219 return;
220 TwoColumnDiff diff = new TwoColumnDiff(
221 ((HistoryWay) reference).getNodes().toArray(),
222 ((HistoryWay) current).getNodes().toArray());
223 referenceNodeListTableModel.setRows(diff.referenceDiff, diff.referenceReversed);
224 currentNodeListTableModel.setRows(diff.currentDiff, false);
225 }
226
227 private void initMemberListTableModels() {
228 if (current == null || current.getType() != OsmPrimitiveType.RELATION
229 || reference == null || reference.getType() != OsmPrimitiveType.RELATION)
230 return;
231 TwoColumnDiff diff = new TwoColumnDiff(
232 ((HistoryRelation) reference).getMembers().toArray(),
233 ((HistoryRelation) current).getMembers().toArray());
234 referenceRelationMemberTableModel.setRows(diff.referenceDiff, diff.referenceReversed);
235 currentRelationMemberTableModel.setRows(diff.currentDiff, false);
236 }
237
238 /**
239 * Replies the tag table model for the respective point in time.
240 *
241 * @param pointInTimeType the type of the point in time (must not be null)
242 * @return the tag table model
243 * @throws IllegalArgumentException if pointInTimeType is null
244 */
245 public TagTableModel getTagTableModel(PointInTimeType pointInTimeType) {
246 CheckParameterUtil.ensureParameterNotNull(pointInTimeType, "pointInTimeType");
247 if (pointInTimeType == PointInTimeType.CURRENT_POINT_IN_TIME)
248 return currentTagTableModel;
249 else // REFERENCE_POINT_IN_TIME
250 return referenceTagTableModel;
251 }
252
253 /**
254 * Replies the node list table model for the respective point in time.
255 *
256 * @param pointInTimeType the type of the point in time (must not be null)
257 * @return the node list table model
258 * @throws IllegalArgumentException if pointInTimeType is null
259 */
260 public DiffTableModel getNodeListTableModel(PointInTimeType pointInTimeType) {
261 CheckParameterUtil.ensureParameterNotNull(pointInTimeType, "pointInTimeType");
262 if (pointInTimeType == PointInTimeType.CURRENT_POINT_IN_TIME)
263 return currentNodeListTableModel;
264 else // REFERENCE_POINT_IN_TIME
265 return referenceNodeListTableModel;
266 }
267
268 /**
269 * Replies the relation member table model for the respective point in time.
270 *
271 * @param pointInTimeType the type of the point in time (must not be null)
272 * @return the relation member table model
273 * @throws IllegalArgumentException if pointInTimeType is null
274 */
275 public DiffTableModel getRelationMemberTableModel(PointInTimeType pointInTimeType) {
276 CheckParameterUtil.ensureParameterNotNull(pointInTimeType, "pointInTimeType");
277 if (pointInTimeType == PointInTimeType.CURRENT_POINT_IN_TIME)
278 return currentRelationMemberTableModel;
279 else // REFERENCE_POINT_IN_TIME
280 return referenceRelationMemberTableModel;
281 }
282
283 /**
284 * Sets the {@link HistoryOsmPrimitive} which plays the role of a reference point
285 * in time (see {@link PointInTimeType}).
286 *
287 * @param reference the reference history primitive. Must not be null.
288 * @throws IllegalArgumentException if reference is null
289 * @throws IllegalStateException if this model isn't a assigned a history yet
290 * @throws IllegalArgumentException if reference isn't an history primitive for the history managed by this mode
291 *
292 * @see #setHistory(History)
293 * @see PointInTimeType
294 */
295 public void setReferencePointInTime(HistoryOsmPrimitive reference) {
296 CheckParameterUtil.ensureParameterNotNull(reference, "reference");
297 if (history == null)
298 throw new IllegalStateException(tr("History not initialized yet. Failed to set reference primitive."));
299 if (reference.getId() != history.getId())
300 throw new IllegalArgumentException(
301 tr("Failed to set reference. Reference ID {0} does not match history ID {1}.", reference.getId(), history.getId()));
302 if (history.getByVersion(reference.getVersion()) == null)
303 throw new IllegalArgumentException(
304 tr("Failed to set reference. Reference version {0} not available in history.", reference.getVersion()));
305
306 this.reference = reference;
307 initTagTableModels();
308 initNodeListTableModels();
309 initMemberListTableModels();
310 fireStateChanged();
311 }
312
313 /**
314 * Sets the {@link HistoryOsmPrimitive} which plays the role of the current point
315 * in time (see {@link PointInTimeType}).
316 *
317 * @param current the reference history primitive. Must not be {@code null}.
318 * @throws IllegalArgumentException if reference is {@code null}
319 * @throws IllegalStateException if this model isn't a assigned a history yet
320 * @throws IllegalArgumentException if reference isn't an history primitive for the history managed by this mode
321 *
322 * @see #setHistory(History)
323 * @see PointInTimeType
324 */
325 public void setCurrentPointInTime(HistoryOsmPrimitive current) {
326 CheckParameterUtil.ensureParameterNotNull(current, "current");
327 if (history == null)
328 throw new IllegalStateException(tr("History not initialized yet. Failed to set current primitive."));
329 if (current.getId() != history.getId())
330 throw new IllegalArgumentException(
331 tr("Failed to set reference. Reference ID {0} does not match history ID {1}.", current.getId(), history.getId()));
332 if (history.getByVersion(current.getVersion()) == null)
333 throw new IllegalArgumentException(
334 tr("Failed to set current primitive. Current version {0} not available in history.", current.getVersion()));
335 this.current = current;
336 initTagTableModels();
337 initNodeListTableModels();
338 initMemberListTableModels();
339 fireStateChanged();
340 }
341
342 /**
343 * Replies the history OSM primitive for the {@link PointInTimeType#CURRENT_POINT_IN_TIME}
344 *
345 * @return the history OSM primitive for the {@link PointInTimeType#CURRENT_POINT_IN_TIME} (may be null)
346 */
347 public HistoryOsmPrimitive getCurrentPointInTime() {
348 return getPointInTime(PointInTimeType.CURRENT_POINT_IN_TIME);
349 }
350
351 /**
352 * Replies the history OSM primitive for the {@link PointInTimeType#REFERENCE_POINT_IN_TIME}
353 *
354 * @return the history OSM primitive for the {@link PointInTimeType#REFERENCE_POINT_IN_TIME} (may be null)
355 */
356 public HistoryOsmPrimitive getReferencePointInTime() {
357 return getPointInTime(PointInTimeType.REFERENCE_POINT_IN_TIME);
358 }
359
360 /**
361 * replies the history OSM primitive for a given point in time
362 *
363 * @param type the type of the point in time (must not be null)
364 * @return the respective primitive. Can be null.
365 * @throws IllegalArgumentException if type is null
366 */
367 public HistoryOsmPrimitive getPointInTime(PointInTimeType type) {
368 CheckParameterUtil.ensureParameterNotNull(type, "type");
369 if (type == PointInTimeType.CURRENT_POINT_IN_TIME)
370 return current;
371 else if (type == PointInTimeType.REFERENCE_POINT_IN_TIME)
372 return reference;
373
374 // should not happen
375 return null;
376 }
377
378 /**
379 * Returns true if <code>primitive</code> is the latest primitive
380 * representing the version currently edited in the current data layer.
381 *
382 * @param primitive the primitive to check
383 * @return true if <code>primitive</code> is the latest primitive
384 */
385 public boolean isLatest(HistoryOsmPrimitive primitive) {
386 return primitive != null && primitive == latest;
387 }
388
389 /**
390 * Sets the reference point in time to the given row.
391 * @param row row number
392 */
393 public void setReferencePointInTime(int row) {
394 if (history == null)
395 return;
396 if (row == history.getNumVersions()) {
397 if (latest != null) {
398 setReferencePointInTime(latest);
399 }
400 return;
401 }
402 if (row < 0 || row > history.getNumVersions())
403 return;
404 setReferencePointInTime(history.get(row));
405 }
406
407 /**
408 * Sets the current point in time to the given row.
409 * @param row row number
410 */
411 public void setCurrentPointInTime(int row) {
412 if (history == null)
413 return;
414 if (row == history.getNumVersions()) {
415 if (latest != null) {
416 setCurrentPointInTime(latest);
417 }
418 return;
419 }
420 if (row < 0 || row > history.getNumVersions())
421 return;
422 setCurrentPointInTime(history.get(row));
423 }
424
425 /**
426 * Determines if the given row is the reference point in time.
427 * @param row row number
428 * @return {@code true} if the given row is the reference point in time
429 */
430 public boolean isReferencePointInTime(int row) {
431 if (history == null)
432 return false;
433 if (row == history.getNumVersions())
434 return latest == reference;
435 if (row < 0 || row > history.getNumVersions())
436 return false;
437 return history.get(row) == reference;
438 }
439
440 /**
441 * Determines if the given row is the current point in time.
442 * @param row row number
443 * @return {@code true} if the given row is the current point in time
444 */
445 public boolean isCurrentPointInTime(int row) {
446 if (history == null)
447 return false;
448 if (row == history.getNumVersions())
449 return latest == current;
450 if (row < 0 || row > history.getNumVersions())
451 return false;
452 return history.get(row) == current;
453 }
454
455 /**
456 * Returns the {@code HistoryPrimitive} at the given row.
457 * @param row row number
458 * @return the {@code HistoryPrimitive} at the given row
459 */
460 public HistoryOsmPrimitive getPrimitive(int row) {
461 if (history == null)
462 return null;
463 return isLatest(row) ? latest : history.get(row);
464 }
465
466 /**
467 * Determines if the given row is the latest.
468 * @param row row number
469 * @return {@code true} if the given row is the latest
470 */
471 public boolean isLatest(int row) {
472 return row >= history.getNumVersions();
473 }
474
475 /**
476 * Returns the latest {@code HistoryOsmPrimitive}.
477 * @return the latest {@code HistoryOsmPrimitive}
478 * @since 11646
479 */
480 public HistoryOsmPrimitive getLatest() {
481 return latest;
482 }
483
484 /**
485 * Returns the key set (union of current and reference point in type key sets).
486 * @return the key set (union of current and reference point in type key sets)
487 * @since 11647
488 */
489 public Set<String> getKeySet() {
490 Set<String> keySet = new HashSet<>();
491 if (current != null) {
492 keySet.addAll(current.getTags().keySet());
493 }
494 if (reference != null) {
495 keySet.addAll(reference.getTags().keySet());
496 }
497 return keySet;
498 }
499
500 /**
501 * Sets the latest {@code HistoryOsmPrimitive}.
502 * @param latest the latest {@code HistoryOsmPrimitive}
503 */
504 protected void setLatest(HistoryOsmPrimitive latest) {
505 if (latest == null) {
506 if (this.current == this.latest) {
507 this.current = history != null ? history.getLatest() : null;
508 }
509 if (this.reference == this.latest) {
510 this.reference = history != null ? history.getLatest() : null;
511 }
512 this.latest = null;
513 } else {
514 if (this.current == this.latest) {
515 this.current = latest;
516 }
517 if (this.reference == this.latest) {
518 this.reference = latest;
519 }
520 this.latest = latest;
521 }
522 fireModelChange();
523 }
524
525 /**
526 * Removes this model as listener for data change and layer change events.
527 *
528 */
529 public void unlinkAsListener() {
530 DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
531 if (ds != null) {
532 ds.removeDataSetListener(this);
533 }
534 MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
535 }
536
537 /* ---------------------------------------------------------------------- */
538 /* DataSetListener */
539 /* ---------------------------------------------------------------------- */
540 @Override
541 public void nodeMoved(NodeMovedEvent event) {
542 Node node = event.getNode();
543 if (!node.isNew() && node.getId() == history.getId()) {
544 setLatest(new HistoryPrimitiveBuilder().build(node));
545 }
546 }
547
548 @Override
549 public void primitivesAdded(PrimitivesAddedEvent event) {
550 for (OsmPrimitive p: event.getPrimitives()) {
551 if (canShowAsLatest(p)) {
552 setLatest(new HistoryPrimitiveBuilder().build(p));
553 }
554 }
555 }
556
557 @Override
558 public void primitivesRemoved(PrimitivesRemovedEvent event) {
559 for (OsmPrimitive p: event.getPrimitives()) {
560 if (!p.isNew() && p.getId() == history.getId()) {
561 setLatest(null);
562 }
563 }
564 }
565
566 @Override
567 public void relationMembersChanged(RelationMembersChangedEvent event) {
568 Relation r = event.getRelation();
569 if (!r.isNew() && r.getId() == history.getId()) {
570 setLatest(new HistoryPrimitiveBuilder().build(r));
571 }
572 }
573
574 @Override
575 public void tagsChanged(TagsChangedEvent event) {
576 OsmPrimitive prim = event.getPrimitive();
577 if (!prim.isNew() && prim.getId() == history.getId()) {
578 setLatest(new HistoryPrimitiveBuilder().build(prim));
579 }
580 }
581
582 @Override
583 public void wayNodesChanged(WayNodesChangedEvent event) {
584 Way way = event.getChangedWay();
585 if (!way.isNew() && way.getId() == history.getId()) {
586 setLatest(new HistoryPrimitiveBuilder().build(way));
587 }
588 }
589
590 @Override
591 public void dataChanged(DataChangedEvent event) {
592 if (history == null)
593 return;
594 OsmPrimitive primitive = event.getDataset().getPrimitiveById(history.getId(), history.getType());
595 HistoryOsmPrimitive newLatest;
596 if (canShowAsLatest(primitive)) {
597 newLatest = new HistoryPrimitiveBuilder().build(primitive);
598 } else {
599 newLatest = null;
600 }
601 setLatest(newLatest);
602 fireModelChange();
603 }
604
605 @Override
606 public void otherDatasetChange(AbstractDatasetChangedEvent event) {
607 // Irrelevant
608 }
609
610 /* ---------------------------------------------------------------------- */
611 /* ActiveLayerChangeListener */
612 /* ---------------------------------------------------------------------- */
613 @Override
614 public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
615 Layer oldLayer = e.getPreviousActiveLayer();
616 if (oldLayer instanceof OsmDataLayer) {
617 OsmDataLayer l = (OsmDataLayer) oldLayer;
618 l.getDataSet().removeDataSetListener(this);
619 }
620 Layer newLayer = e.getSource().getActiveLayer();
621 if (!(newLayer instanceof OsmDataLayer)) {
622 latest = null;
623 fireModelChange();
624 return;
625 }
626 OsmDataLayer l = (OsmDataLayer) newLayer;
627 l.getDataSet().addDataSetListener(this);
628 OsmPrimitive primitive = history != null ? l.data.getPrimitiveById(history.getId(), history.getType()) : null;
629 HistoryOsmPrimitive newLatest;
630 if (canShowAsLatest(primitive)) {
631 newLatest = new HistoryPrimitiveBuilder().build(primitive);
632 } else {
633 newLatest = null;
634 }
635 setLatest(newLatest);
636 fireModelChange();
637 }
638
639 /**
640 * Creates a {@link HistoryOsmPrimitive} from a {@link OsmPrimitive}
641 *
642 */
643 static class HistoryPrimitiveBuilder implements OsmPrimitiveVisitor {
644 private HistoryOsmPrimitive clone;
645
646 @Override
647 public void visit(Node n) {
648 clone = new HistoryNode(n.getId(), n.getVersion(), n.isVisible(), getCurrentUser(), 0, null, n.getCoor(), false);
649 clone.setTags(n.getKeys());
650 }
651
652 @Override
653 public void visit(Relation r) {
654 clone = new HistoryRelation(r.getId(), r.getVersion(), r.isVisible(), getCurrentUser(), 0, null, false);
655 clone.setTags(r.getKeys());
656 HistoryRelation hr = (HistoryRelation) clone;
657 for (RelationMember rm : r.getMembers()) {
658 hr.addMember(new RelationMemberData(rm.getRole(), rm.getType(), rm.getUniqueId()));
659 }
660 }
661
662 @Override
663 public void visit(Way w) {
664 clone = new HistoryWay(w.getId(), w.getVersion(), w.isVisible(), getCurrentUser(), 0, null, false);
665 clone.setTags(w.getKeys());
666 for (Node n: w.getNodes()) {
667 ((HistoryWay) clone).addNode(n.getUniqueId());
668 }
669 }
670
671 private static User getCurrentUser() {
672 UserInfo info = UserIdentityManager.getInstance().getUserInfo();
673 return info == null ? User.getAnonymous() : User.createOsmUser(info.getId(), info.getDisplayName());
674 }
675
676 HistoryOsmPrimitive build(OsmPrimitive primitive) {
677 primitive.accept(this);
678 return clone;
679 }
680 }
681
682}
Note: See TracBrowser for help on using the repository browser.