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

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

enable PMD rule OptimizableToArrayCall

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