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

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

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

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