source: josm/trunk/src/org/openstreetmap/josm/command/Command.java@ 2946

Last change on this file since 2946 was 2932, checked in by mjulius, 14 years ago

bring PrimitiveData.getId() in line with OsmPrimitive.getId()
remove OsmReader.OsmPrimitiveData and use PrimitiveData instead

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.command;
3
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.Map;
8import java.util.Map.Entry;
9
10import javax.swing.tree.MutableTreeNode;
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.PrimitiveData;
16import org.openstreetmap.josm.data.osm.Relation;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
19import org.openstreetmap.josm.gui.layer.Layer;
20import org.openstreetmap.josm.gui.layer.OsmDataLayer;
21import org.openstreetmap.josm.tools.CheckParameterUtil;
22
23/**
24 * Classes implementing Command modify a dataset in a specific way. A command is
25 * one atomic action on a specific dataset, such as move or delete.
26 *
27 * The command remembers the {@see OsmDataLayer} it is operating on.
28 *
29 * @author imi
30 */
31abstract public class Command {
32
33 private static final class CloneVisitor extends AbstractVisitor {
34 public Map<OsmPrimitive, PrimitiveData> orig = new HashMap<OsmPrimitive, PrimitiveData>();
35
36 public void visit(Node n) {
37 orig.put(n, n.save());
38 }
39 public void visit(Way w) {
40 orig.put(w, w.save());
41 }
42 public void visit(Relation e) {
43 orig.put(e, e.save());
44 }
45 }
46
47 /** the map of OsmPrimitives in the original state to OsmPrimitives in cloned state */
48 private Map<OsmPrimitive, PrimitiveData> cloneMap = new HashMap<OsmPrimitive, PrimitiveData>();
49
50 /** the layer which this command is applied to */
51 private OsmDataLayer layer;
52
53 public Command() {
54 this.layer = Main.map.mapView.getEditLayer();
55 }
56
57 /**
58 * Creates a new command in the context of a specific data layer
59 *
60 * @param layer the data layer. Must not be null.
61 * @throws IllegalArgumentException thrown if layer is null
62 */
63 public Command(OsmDataLayer layer) throws IllegalArgumentException {
64 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
65 this.layer = layer;
66 }
67
68 /**
69 * Executes the command on the dataset. This implementation will remember all
70 * primitives returned by fillModifiedData for restoring them on undo.
71 */
72 public boolean executeCommand() {
73 CloneVisitor visitor = new CloneVisitor();
74 Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
75 fillModifiedData(all, all, all);
76 for (OsmPrimitive osm : all) {
77 osm.visit(visitor);
78 }
79 cloneMap = visitor.orig;
80 return true;
81 }
82
83 /**
84 * Undoes the command.
85 * It can be assumed that all objects are in the same state they were before.
86 * It can also be assumed that executeCommand was called exactly once before.
87 *
88 * This implementation undoes all objects stored by a former call to executeCommand.
89 */
90 public void undoCommand() {
91 for (Entry<OsmPrimitive, PrimitiveData> e : cloneMap.entrySet()) {
92 OsmPrimitive primitive = e.getKey();
93 if (primitive.getDataSet() != null) {
94 e.getKey().load(e.getValue());
95 }
96 }
97 }
98
99 /**
100 * Called when a layer has been removed to have the command remove itself from
101 * any buffer if it is not longer applicable to the dataset (e.g. it was part of
102 * the removed layer)
103 *
104 * @param oldLayer the old layer
105 * @return true if this command
106 */
107 public boolean invalidBecauselayerRemoved(Layer oldLayer) {
108 if (!(oldLayer instanceof OsmDataLayer))
109 return false;
110 return layer == oldLayer;
111 }
112
113 /**
114 * Lets other commands access the original version
115 * of the object. Usually for undoing.
116 */
117 public PrimitiveData getOrig(OsmPrimitive osm) {
118 PrimitiveData o = cloneMap.get(osm);
119 if (o != null)
120 return o;
121 Main.debug("unable to find osm with id: " + osm.getId() + " hashCode: " + osm.hashCode());
122 for (OsmPrimitive t : cloneMap.keySet()) {
123 PrimitiveData to = cloneMap.get(t);
124 Main.debug("now: " + t.getId() + " hashCode: " + t.hashCode());
125 Main.debug("orig: " + to.getUniqueId() + " hashCode: " + to.hashCode());
126 }
127 return o;
128 }
129
130 /**
131 * Replies the layer this command is (or was) applied to.
132 *
133 * @return
134 */
135 protected OsmDataLayer getLayer() {
136 return layer;
137 }
138
139 /**
140 * Fill in the changed data this command operates on.
141 * Add to the lists, don't clear them.
142 *
143 * @param modified The modified primitives
144 * @param deleted The deleted primitives
145 * @param added The added primitives
146 */
147 abstract public void fillModifiedData(Collection<OsmPrimitive> modified,
148 Collection<OsmPrimitive> deleted,
149 Collection<OsmPrimitive> added);
150
151 abstract public MutableTreeNode description();
152
153}
Note: See TracBrowser for help on using the repository browser.