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

Last change on this file since 3262 was 3262, checked in by bastiK, 14 years ago

extended command list dialog; added inspection panel

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