source: josm/trunk/src/org/openstreetmap/josm/command/SequenceCommand.java@ 12749

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

see #13036 - deprecate Command() default constructor, fix unit tests and java warnings

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Arrays;
7import java.util.Collection;
8import java.util.HashSet;
9import java.util.Objects;
10
11import javax.swing.Icon;
12
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.gui.layer.Layer;
16import org.openstreetmap.josm.tools.ImageProvider;
17import org.openstreetmap.josm.tools.Utils;
18
19/**
20 * A command consisting of a sequence of other commands. Executes the other commands
21 * and undo them in reverse order.
22 * @author imi
23 * @since 31
24 */
25public class SequenceCommand extends Command {
26
27 /** The command sequence to be executed. */
28 private Command[] sequence;
29 private boolean sequenceComplete;
30 private final String name;
31 /** Determines if the sequence execution should continue after one of its commands fails. */
32 protected final boolean continueOnError;
33
34 /**
35 * Create the command by specifying the list of commands to execute.
36 * @param ds The target data set. Must not be {@code null}
37 * @param name The description text
38 * @param sequenz The sequence that should be executed
39 * @param continueOnError Determines if the sequence execution should continue after one of its commands fails
40 * @since 12726
41 */
42 public SequenceCommand(DataSet ds, String name, Collection<Command> sequenz, boolean continueOnError) {
43 super(ds);
44 this.name = name;
45 this.sequence = sequenz.toArray(new Command[sequenz.size()]);
46 this.continueOnError = continueOnError;
47 }
48
49 /**
50 * Create the command by specifying the list of commands to execute.
51 * @param name The description text
52 * @param sequenz The sequence that should be executed. Must not be null or empty
53 * @param continueOnError Determines if the sequence execution should continue after one of its commands fails
54 * @since 11874
55 */
56 public SequenceCommand(String name, Collection<Command> sequenz, boolean continueOnError) {
57 this(sequenz.iterator().next().getAffectedDataSet(), name, sequenz, continueOnError);
58 }
59
60 /**
61 * Create the command by specifying the list of commands to execute.
62 * @param name The description text
63 * @param sequenz The sequence that should be executed.
64 */
65 public SequenceCommand(String name, Collection<Command> sequenz) {
66 this(name, sequenz, false);
67 }
68
69 /**
70 * Convenient constructor, if the commands are known at compile time.
71 * @param name The description text
72 * @param sequenz The sequence that should be executed.
73 */
74 public SequenceCommand(String name, Command... sequenz) {
75 this(name, Arrays.asList(sequenz));
76 }
77
78 @Override public boolean executeCommand() {
79 for (int i = 0; i < sequence.length; i++) {
80 boolean result = sequence[i].executeCommand();
81 if (!result && !continueOnError) {
82 undoCommands(i-1);
83 return false;
84 }
85 }
86 sequenceComplete = true;
87 return true;
88 }
89
90 /**
91 * Returns the last command.
92 * @return The last command, or {@code null} if the sequence is empty.
93 */
94 public Command getLastCommand() {
95 if (sequence.length == 0)
96 return null;
97 return sequence[sequence.length-1];
98 }
99
100 protected final void undoCommands(int start) {
101 for (int i = start; i >= 0; --i) {
102 sequence[i].undoCommand();
103 }
104 }
105
106 @Override public void undoCommand() {
107 // We probably aborted this halfway though the
108 // execution sequence because of a sub-command
109 // error. We already undid the sub-commands.
110 if (!sequenceComplete)
111 return;
112 undoCommands(sequence.length-1);
113 }
114
115 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
116 for (Command c : sequence) {
117 c.fillModifiedData(modified, deleted, added);
118 }
119 }
120
121 @Override
122 public String getDescriptionText() {
123 return tr("Sequence: {0}", name);
124 }
125
126 @Override
127 public Icon getDescriptionIcon() {
128 return ImageProvider.get("data", "sequence");
129 }
130
131 @Override
132 public Collection<PseudoCommand> getChildren() {
133 return Arrays.<PseudoCommand>asList(sequence);
134 }
135
136 @Override
137 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
138 Collection<OsmPrimitive> prims = new HashSet<>();
139 for (Command c : sequence) {
140 prims.addAll(c.getParticipatingPrimitives());
141 }
142 return prims;
143 }
144
145 protected final void setSequence(Command... sequence) {
146 this.sequence = Utils.copyArray(sequence);
147 }
148
149 protected final void setSequenceComplete(boolean sequenceComplete) {
150 this.sequenceComplete = sequenceComplete;
151 }
152
153 /**
154 * Invalidate all layers that were affected by this command.
155 * @see Layer#invalidate()
156 * @deprecated to be removed end of 2017.
157 */
158 @Override
159 @Deprecated
160 public void invalidateAffectedLayers() {
161 super.invalidateAffectedLayers();
162 for (Command c : sequence) {
163 c.invalidateAffectedLayers();
164 }
165 }
166
167 @Override
168 public int hashCode() {
169 return Objects.hash(super.hashCode(), Arrays.hashCode(sequence), sequenceComplete, name, continueOnError);
170 }
171
172 @Override
173 public boolean equals(Object obj) {
174 if (this == obj) return true;
175 if (obj == null || getClass() != obj.getClass()) return false;
176 if (!super.equals(obj)) return false;
177 SequenceCommand that = (SequenceCommand) obj;
178 return sequenceComplete == that.sequenceComplete &&
179 continueOnError == that.continueOnError &&
180 Arrays.equals(sequence, that.sequence) &&
181 Objects.equals(name, that.name);
182 }
183}
Note: See TracBrowser for help on using the repository browser.