Evaluating Software Design Patterns
— the "Gang of Four" patterns implemented in Java 6

dk.rode.thesis.command
Class CompositeCommand<E>

java.lang.Object
  extended by dk.rode.thesis.command.CompositeCommand<E>
Type Parameters:
E - The type of result obtained by executing all contained commands in this composite command.
All Implemented Interfaces:
Command<E>, Copyable<Command<E>>, StrictCopyable<Command<E>>, Iterable<Command<E>>

@Participant(value="ConcreteCommand")
public class CompositeCommand<E>
extends Object
implements Command<E>, Iterable<Command<E>>

A composite command is a command that represents an number of other contained commands, possibly composite as well, thus forming a tree-like structure.

Composite commands are simple containers that do not maintain parent references. Contained commands do not know they are contained unless this information is stored locally. Hence, when a composite command is executed, graph traversal is top-down only, in a depth-first manner; the result of the last executed command is returned.

A composite command is undoable if all contained commands are undoable. If the execution fails for the n'th command, the commands from n to zero will be undone when undo() is invoked, i.e. in reverse order. The returned results is the result from the last undone command, i.e. the command at index zero (which may be composite as well).

The value returned from execute() and undo() is the result from the last command in this composite sequence! For execute, this is the last command executed, while for undo is it the value of the first undone command.

The result of executing a failed composite command again without having undo the previous error is undefined.

Composite commands compares based on identity (==).

Author:
Gunni Rode / rode.dk

Field Summary
private  List<Command<E>> commands
          The commands associated with this command, in order.
private  int index
          The index identifying the current command being executed or undone.
 
Constructor Summary
CompositeCommand()
          No-arg constructor.
CompositeCommand(Command<E>... commands)
          Constructor, which adds each copies each command in commands and adds it to this composite command.
CompositeCommand(CompositeCommand<E> command)
          Copy constructor, which copies each associated command in command and adds it to this composite command.
 
Method Summary
 boolean addCommand(Command<E> command)
          Associates the command supplied as command to this composite command, if not already.
 CompositeCommand<E> copy()
          Creates a copy of this command, excluding internal state information required for execution and undo.
 List<Command<E>> execute()
          Performs the execution of this command.
 List<Command<E>> getCommands()
          Returns the commands currently associated with this composite command, in order.
<V extends Command<E>>
List<V>
getCommands(Class<V> type)
          Returns the commands currently associated with this composite command, in order, assignable to the type supplied as type.
 E getResult()
          Returns the result of the last executed command contained in this composite command.
 boolean isUndoable()
          Returns true if this command has been executed and is undoable, false if not.
 Iterator<Command<E>> iterator()
          Returns an iterator to iterate through this composite command, which is backed by this composite commands, i.e.
 boolean removeCommand(Command<?> command)
          Removes the command supplied as command from this composite command, if associated.
 int size()
          Returns the number of associated commands to this composite command.
 String toString()
          Returns the string representation if this composite command.
 E undo()
          Perform undo of this command, if possible.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

commands

private final List<Command<E>> commands
The commands associated with this command, in order.

Never null, but can be null.


index

private int index
The index identifying the current command being executed or undone.

Range: 0 <= index <= commands.size()

Constructor Detail

CompositeCommand

public CompositeCommand()
No-arg constructor.


CompositeCommand

public CompositeCommand(Command<E>... commands)
Constructor, which adds each copies each command in commands and adds it to this composite command.

Duplicate commands are ignored.

Parameters:
commands - The (copied) commands to add; cannot contain null entries.
Throws:
NullPointerException - If commands contain a null entry.

CompositeCommand

public CompositeCommand(CompositeCommand<E> command)
Copy constructor, which copies each associated command in command and adds it to this composite command.

Parameters:
command - The composite command to copy; cannot be null.
Throws:
NullPointerException - If command is null.
Method Detail

addCommand

public boolean addCommand(Command<E> command)
Associates the command supplied as command to this composite command, if not already.

If already added, this method does nothing.

Parameters:
command - The command to add; cannot be null.
Returns:
True if command was added, false if not, i.e. if already added.
Throws:
NullPointerException - If command is null.
IllegalArgumentException - If this composite command is tried added to it self.
See Also:
removeCommand(Command)

copy

public CompositeCommand<E> copy()
Description copied from interface: Command
Creates a copy of this command, excluding internal state information required for execution and undo.

Specified by:
copy in interface Command<E>
Specified by:
copy in interface Copyable<Command<E>>
Returns:
A new instance of this command; never null.

execute

public List<Command<E>> execute()
                         throws CommandException
Description copied from interface: Command
Performs the execution of this command.

After successful execution, the result of the execution can be obtained via the Command.getResult() method.

Specified by:
execute in interface Command<E>
Returns:
A list containing all spawned commands from contained commands; never null, but can be empty.
Throws:
CommandException - If the execution fails.
See Also:
Command.undo()

getCommands

public List<Command<E>> getCommands()
Returns the commands currently associated with this composite command, in order.

Modifying the returned collection will not affect this command.

Returns:
The collection of associated commands; never null, but can be empty.
See Also:
size()

getCommands

public <V extends Command<E>> List<V> getCommands(Class<V> type)
Returns the commands currently associated with this composite command, in order, assignable to the type supplied as type.

Invoking this method with the Command interface corresponds to invoking getCommands().

Modifying the returned collection will not affect this command.

Type Parameters:
V - The type of applicable commands.
Parameters:
type - The (super-)class of commands to include; cannot be null.
Returns:
The collection of associated commands of the type supplied as type; never null, but can be empty.
Throws:
NullPointerException - If type is null.

getResult

public E getResult()
Returns the result of the last executed command contained in this composite command.

Specified by:
getResult in interface Command<E>
Returns:
The result of the execution; can be null.

isUndoable

public boolean isUndoable()
Description copied from interface: Command
Returns true if this command has been executed and is undoable, false if not.

If undoable, the effect of the execution can be undone by invoking Command.undo().

Specified by:
isUndoable in interface Command<E>
Returns:
True if undoable, false if not.

iterator

public Iterator<Command<E>> iterator()
Returns an iterator to iterate through this composite command, which is backed by this composite commands, i.e. changes to the iterator changes this command.

Specified by:
iterator in interface Iterable<Command<E>>
Returns:
An iterator backed by this composite command; never null.

removeCommand

public boolean removeCommand(Command<?> command)
Removes the command supplied as command from this composite command, if associated.

If not associated, this method does nothing.

Parameters:
command - The command to remove; cannot be null.
Returns:
True if command was removed, false if not, i.e. if not previously added.
Throws:
NullPointerException - If command is null.
See Also:
addCommand(Command)

size

public int size()
Returns the number of associated commands to this composite command.

Returns:
The number of commands.

toString

public String toString()
Returns the string representation if this composite command.

Overrides:
toString in class Object
Returns:
The string representation; never null.

undo

public E undo()
       throws CommandException
Description copied from interface: Command
Perform undo of this command, if possible.

If this method is invoked and this command is not undoable, an exception will be thrown.

The result of invoking undo on a command that has not been executed is undefined.

Specified by:
undo in interface Command<E>
Returns:
The result of the undo operation; may be null.
Throws:
CommandException - If the undo fails.

Gunni Rode / rode.dk

Feel free to use and/or modify the Java 6 source code developed for this thesis AT YOUR OWN RISK, but note that the source code comes WITHOUT ANY — and I do mean WITHOUT ANY — form of warranty WHAT SO EVER!

The original thesis and source code are available at rode.dk/thesis.