// License: GPL. Copyright 2007 by Immanuel Scholz and others package org.openstreetmap.josm.command; import static org.openstreetmap.josm.tools.I18n.tr; import java.util.Arrays; import java.util.Collection; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.MutableTreeNode; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.osm.OsmPrimitive; /** * A command consisting of a sequence of other commands. Executes the other commands * and undo them in reverse order. * @author imi */ public class SequenceCommand extends Command { /** * The command sequenz to be executed. */ private Command[] sequence; private boolean sequence_complete; private final String name; public boolean continueOnError = false; /** * Create the command by specifying the list of commands to execute. * @param sequenz The sequence that should be executed. */ public SequenceCommand(String name, Collection<Command> sequenz) { super(); this.name = name; this.sequence = new Command[sequenz.size()]; this.sequence = sequenz.toArray(this.sequence); } /** * Convenient constructor, if the commands are known at compile time. */ public SequenceCommand(String name, Command... sequenz) { this(name, Arrays.asList(sequenz)); } @Override public boolean executeCommand() { for (int i=0; i < sequence.length; i++) { Command c = sequence[i]; boolean result = c.executeCommand(); if (!result) { Main.debug("SequenceCommand, executing command[" + i + "] " + c + " result: " + result); } if (!result && !continueOnError) { this.undoCommands(i-1); return false; } } sequence_complete = true; return true; } public Command getLastCommand() { if(sequence.length == 0) return null; return sequence[sequence.length-1]; } private void undoCommands(int start) { // We probably aborted this halfway though the // execution sequence because of a sub-command // error. We already undid the sub-commands. if (!sequence_complete) return; for (int i = start; i >= 0; --i) { sequence[i].undoCommand(); } } @Override public void undoCommand() { this.undoCommands(sequence.length-1); } @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { for (Command c : sequence) { c.fillModifiedData(modified, deleted, added); } } @Override public MutableTreeNode description() { DefaultMutableTreeNode root = new DefaultMutableTreeNode(tr("Sequence")+": "+name); for (Command c : sequence) { root.add(c.description()); } return root; } }