org.eclipse.emf.common.command
Class StrictCompoundCommand

java.lang.Object
  extended by org.eclipse.emf.common.command.AbstractCommand
      extended by org.eclipse.emf.common.command.CompoundCommand
          extended by org.eclipse.emf.common.command.StrictCompoundCommand
All Implemented Interfaces:
Command
Direct Known Subclasses:
CopyCommand, SetCommand.PessimisticStrictCompoundCommand

public class StrictCompoundCommand
extends CompoundCommand

A composite command which assumes that later commands in the list may depend on the results and side-effects of earlier commands in the list. Because of this, it must implement Command.canExecute() more carefully, i.e., in order to determine canExecute for the composite, it doesn't simply test each command. It tests the first command to see if it can execute; then, if there is another command in the list, it checks if the first command can undo and then goes ahead and executes it! This process is repeated until the last command that is not followed by another, which then determines the final result. (For efficiency, when this processing gets to the last command, that command is tested for canUndo too and that result is cached.) All the commands that have been executed are then undone, if isPessimistic is true; by default it's false.

It is important for all but the last command to have no visible side-effect! Multiple commands with visible side-effects must be composed into a single command using just a CompoundCommand and that composite could be the last command of a strict composite.

Here is an example of how this can be used in conjunction with a CommandWrapper.

   Command strictCompoundCommand = new StrictCompoundCommand();
   Command copyCommand = new CopyCommand(...);
   strictCompoundCommand.add(copyCommand);

   Command addCommand =
     new CommandWrapper()
     {
       public Command createCommand()
       {
         new AddCommand(parent, copyCommand.getResult()); 
       }
     };
   strictCompoundCommand.append(addCommand);
 
Here the add command won't know which command to create until it has the result of the copy command. The proxy makes sure the creation of the add command is deferred and the strict composite ensures that execution dependencies are met.


Nested Class Summary
 
Nested classes/interfaces inherited from class org.eclipse.emf.common.command.AbstractCommand
AbstractCommand.NonDirtying
 
Field Summary
protected  boolean isPessimistic
          Whether commands that have been tentatively executed need to be undone.
protected  boolean isUndoable
          The result for Command.canUndo().
protected  int rightMostExecutedCommandIndex
          Remember to call redo instead of execute for any command at or before this index in the list.
 
Fields inherited from class org.eclipse.emf.common.command.CompoundCommand
commandList, LAST_COMMAND_ALL, MERGE_COMMAND_ALL, resultIndex
 
Fields inherited from class org.eclipse.emf.common.command.AbstractCommand
description, isExecutable, isPrepared, label
 
Constructor Summary
StrictCompoundCommand()
          Creates an empty instance.
StrictCompoundCommand(java.util.List<Command> commandList)
          Creates an instance with the given command list.
StrictCompoundCommand(java.lang.String label)
          Creates an instance with the given label.
StrictCompoundCommand(java.lang.String label, java.util.List<Command> commandList)
          Creates an instance with the given label and command list.
StrictCompoundCommand(java.lang.String label, java.lang.String description)
          Creates an instance with the given label and description.
StrictCompoundCommand(java.lang.String label, java.lang.String description, java.util.List<Command> commandList)
          Creates an instance with the given label, description, and command list.
 
Method Summary
 boolean appendAndExecute(Command command)
          Checks if the command can execute; if so, it is executed, appended to the list, and true is returned, if not, it is just disposed and false is returned.
 void execute()
          Calls Command.execute() for each command in the list, but makes sure to call redo for any commands that were previously executed to compute canExecute.
protected  boolean prepare()
          Returns false if any command on the list returns false for Command.canExecute(), or if some command before the last one can't be undone and hence we can't test all the commands for executability.
 void redo()
          Calls Command.redo() for each command in the list.
 java.lang.String toString()
          Returns an abbreviated name using this object's own class' name, without package qualification, followed by a space separated list of field:value pairs.
 void undo()
          Calls Command.undo() for each command in the list.
 
Methods inherited from class org.eclipse.emf.common.command.CompoundCommand
append, appendIfCanExecute, canUndo, dispose, getAffectedObjects, getCommandList, getDescription, getLabel, getMergedAffectedObjectsCollection, getMergedResultCollection, getResult, getResultIndex, isEmpty, unwrap
 
Methods inherited from class org.eclipse.emf.common.command.AbstractCommand
canExecute, chain, setDescription, setLabel
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

isUndoable

protected boolean isUndoable
The result for Command.canUndo().


isPessimistic

protected boolean isPessimistic
Whether commands that have been tentatively executed need to be undone.


rightMostExecutedCommandIndex

protected int rightMostExecutedCommandIndex
Remember to call redo instead of execute for any command at or before this index in the list.

Constructor Detail

StrictCompoundCommand

public StrictCompoundCommand()
Creates an empty instance.


StrictCompoundCommand

public StrictCompoundCommand(java.lang.String label)
Creates an instance with the given label.

Parameters:
label - the label.

StrictCompoundCommand

public StrictCompoundCommand(java.lang.String label,
                             java.lang.String description)
Creates an instance with the given label and description.

Parameters:
label - the label.
description - the description.

StrictCompoundCommand

public StrictCompoundCommand(java.util.List<Command> commandList)
Creates an instance with the given command list.

Parameters:
commandList - the list of commands.

StrictCompoundCommand

public StrictCompoundCommand(java.lang.String label,
                             java.util.List<Command> commandList)
Creates an instance with the given label and command list.

Parameters:
label - the label.
commandList - the list of commands.

StrictCompoundCommand

public StrictCompoundCommand(java.lang.String label,
                             java.lang.String description,
                             java.util.List<Command> commandList)
Creates an instance with the given label, description, and command list.

Parameters:
label - the label.
description - the description.
commandList - the list of commands.
Method Detail

prepare

protected boolean prepare()
Returns false if any command on the list returns false for Command.canExecute(), or if some command before the last one can't be undone and hence we can't test all the commands for executability.

Overrides:
prepare in class CompoundCommand
Returns:
whether the command can execute.

execute

public void execute()
Calls Command.execute() for each command in the list, but makes sure to call redo for any commands that were previously executed to compute canExecute. In the case that isPessimistic is false, only the last command will be executed since the others will have been executed but not undone during prepare().

Specified by:
execute in interface Command
Overrides:
execute in class CompoundCommand

undo

public void undo()
Calls Command.undo() for each command in the list. In the case that isPessimistic is false, only the last command will be undone since the others will have been executed and not undo during prepare().

Specified by:
undo in interface Command
Overrides:
undo in class CompoundCommand

redo

public void redo()
Calls Command.redo() for each command in the list. In the case that isPessimistic is false, only the last command will be redone since the others will have been executed and not undo during prepare().

Specified by:
redo in interface Command
Overrides:
redo in class CompoundCommand

appendAndExecute

public boolean appendAndExecute(Command command)
Checks if the command can execute; if so, it is executed, appended to the list, and true is returned, if not, it is just disposed and false is returned. A typical use for this is to execute commands created during the execution of another command, e.g.,
   class MyCommand extends AbstractCommand
   {
     protected Command subcommand;

     //...

     public void execute()
     {
       // ...
       StrictCompoundCommand subcommands = new StrictCompoundCommand();
       subcommands.appendAndExecute(new AddCommand(...));
       if (condition) subcommands.appendAndExecute(new AddCommand(...));
       subcommand = subcommands.unwrap();
     }

     public void undo()
     {
       // ...
       subcommand.undo();
     }

     public void redo()
     {
       // ...
       subcommand.redo();
     }

     public void dispose()
     {
       // ...
       if (subcommand != null)
      {
         subcommand.dispose();
       }
     }
   }
 

Overrides:
appendAndExecute in class CompoundCommand
Parameters:
command - the command.
Returns:
whether the command was successfully executed and appended.

toString

public java.lang.String toString()
Description copied from class: AbstractCommand
Returns an abbreviated name using this object's own class' name, without package qualification, followed by a space separated list of field:value pairs.

Overrides:
toString in class CompoundCommand
Returns:
string representation.

Copyright 2001-2006 IBM Corporation and others.
All Rights Reserved.