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

Last change on this file since 12718 was 12718, checked in by Don-vip, 3 weeks ago

see #13036 - see #15229 - see #15182 - make Commands depends only on a DataSet, not a Layer. This removes a lot of GUI dependencies

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