/**
* <copyright>
*
* Copyright (c) 2002, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*
* </copyright>
*
* $Id: CompoundCommand.java,v 1.6 2007/06/12 20:56:17 emerks Exp $
*/
package net.enilink.komma.common.command;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.enilink.komma.common.CommonPlugin;
import org.eclipse.core.commands.operations.IUndoableOperation;
/**
* A command that comprises a sequence of subcommands. Derived classes can
* control the way results are accumulated from the individual commands; the
* default behaviour is to return the result of the last command.
*/
public class ExtendedCompositeCommand extends CompositeCommand {
/**
* When {@link #resultIndex} is set to this, {@link #getResult} and
* {@link #getAffectedObjects} are delegated to the last command, if any, in
* the list.
*/
public static final int LAST_COMMAND_ALL = Integer.MIN_VALUE;
/**
* When {@link #resultIndex} is set to this, {@link #getResult} and
* {@link #getAffectedObjects} are set to the result of merging the
* corresponding collection of each command in the list.
*/
public static final int MERGE_COMMAND_ALL = Integer.MIN_VALUE - 1;
/**
* The index of the command whose result and affected objects are forwarded.
* Negative values have special meaning, as defined by the static constants.
* A value of -1 indicates that the last command in the list should be used.
* We could have more special behaviours implemented for other negative
* values.
*/
protected int resultIndex = MERGE_COMMAND_ALL;
/**
* Creates an empty instance.
*/
public ExtendedCompositeCommand() {
super();
}
/**
* Creates an instance with the given label.
*
* @param label
* the label.
*/
public ExtendedCompositeCommand(String label) {
super(label);
}
/**
* Creates an instance with the given label and description.
*
* @param label
* the label.
* @param description
* the description.
*/
public ExtendedCompositeCommand(String label, String description) {
super(label, description, null);
}
/**
* Creates instance with the given label and list.
*
* @param label
* the label.
* @param commandList
* the list of commands.
*/
public ExtendedCompositeCommand(String label, List<ICommand> commandList) {
super(label, commandList);
}
/**
* Creates an instance with the given label, description, and list.
*
* @param label
* the label.
* @param description
* the description.
* @param commandList
* the list of commands.
*/
public ExtendedCompositeCommand(String label, String description,
List<ICommand> commandList) {
super(label, description, commandList);
}
/**
* Creates an empty instance with the given result index.
*
* @param resultIndex
* the {@link #resultIndex}.
*/
public ExtendedCompositeCommand(int resultIndex) {
super();
this.resultIndex = resultIndex;
}
/**
* Creates an instance with the given result index and label.
*
* @param resultIndex
* the {@link #resultIndex}.
* @param label
* the label.
*/
public ExtendedCompositeCommand(int resultIndex, String label) {
super(label);
this.resultIndex = resultIndex;
}
/**
* Creates an instance with the given result index, label, and description.
*
* @param resultIndex
* the {@link #resultIndex}.
* @param label
* the label.
* @param description
* the description.
*/
public ExtendedCompositeCommand(int resultIndex, String label,
String description) {
super(label, description, null);
this.resultIndex = resultIndex;
}
/**
* Creates an instance with the given result index and list.
*
* @param resultIndex
* the {@link #resultIndex}.
* @param commandList
* the list of commands.
*/
public ExtendedCompositeCommand(int resultIndex, List<ICommand> commandList) {
super();
this.resultIndex = resultIndex;
getChildren().addAll(commandList);
}
/**
* Creates an instance with the given resultIndex, label, and list.
*
* @param resultIndex
* the {@link #resultIndex}.
* @param label
* the label.
* @param commandList
* the list of commands.
*/
public ExtendedCompositeCommand(int resultIndex, String label,
List<ICommand> commandList) {
super(label, null, commandList);
this.resultIndex = resultIndex;
}
/**
* Creates an instance with the given result index, label, description, and
* list.
*
* @param resultIndex
* the {@link #resultIndex}.
* @param label
* the label.
* @param description
* the description.
* @param commandList
* the list of commands.
*/
public ExtendedCompositeCommand(int resultIndex, String label,
String description, List<ICommand> commandList) {
super(label, description, commandList);
this.resultIndex = resultIndex;
}
/**
* Returns an unmodifiable view of the commands in the list.
*
* @return an unmodifiable view of the commands in the list.
*/
@SuppressWarnings("unchecked")
public List<? extends ICommand> getCommandList() {
return (List<? extends ICommand>) Collections
.unmodifiableList(getChildren());
}
/**
* Returns the index of the command whose result and affected objects are
* forwarded. Negative values have special meaning, as defined by the static
* constants.
*
* @return the index of the command whose result and affected objects are
* forwarded.
* @see #LAST_COMMAND_ALL
* @see #MERGE_COMMAND_ALL
*/
public int getResultIndex() {
return resultIndex;
}
public String getLabel() {
if (label != null) {
return label;
} else {
List<IUndoableOperation> children = getChildren();
if (getChildren().isEmpty()) {
return CommonPlugin.INSTANCE
.getString("_UI_AbstractCommand_label");
} else if (resultIndex == LAST_COMMAND_ALL
|| resultIndex == MERGE_COMMAND_ALL) {
return children.get(children.size() - 1).getLabel();
} else if (resultIndex < children.size()) {
return children.get(resultIndex).getLabel();
}
}
return super.getLabel();
}
/**
* Determines the result by composing the results of the commands in the
* list; this is affected by the setting of {@link #resultIndex}.
*
* @return the result.
*/
@Override
protected Object getReturnValues() {
if (getChildren().isEmpty()) {
return null;
} else if (resultIndex == LAST_COMMAND_ALL) {
IUndoableOperation command = getChildren().get(
getChildren().size() - 1);
if (command instanceof ICommand) {
return ((ICommand) command).getCommandResult().getReturnValue();
}
} else if (resultIndex == MERGE_COMMAND_ALL) {
return super.getReturnValues();
} else if (resultIndex < getChildren().size()) {
IUndoableOperation command = getChildren().get(resultIndex);
if (command instanceof ICommand) {
return ((ICommand) command).getCommandResult().getReturnValue();
}
}
return null;
}
/**
* Determines the affected objects by composing the affected objects of the
* commands in the list; this is affected by the setting of
* {@link #resultIndex}.
*
* @return the affected objects.
*/
@Override
public Collection<?> getAffectedObjects() {
if (getChildren().isEmpty()) {
return Collections.EMPTY_LIST;
} else if (resultIndex == LAST_COMMAND_ALL) {
return ((ICommand) getChildren().get(getChildren().size() - 1))
.getAffectedObjects();
} else if (resultIndex == MERGE_COMMAND_ALL) {
return super.getAffectedObjects();
} else if (resultIndex < getChildren().size()) {
return ((ICommand) getChildren().get(resultIndex))
.getAffectedObjects();
} else {
return Collections.EMPTY_LIST;
}
}
@Override
public String toString() {
StringBuffer result = new StringBuffer(super.toString());
result.append(" (commandList: #" + getChildren().size() + ")");
result.append(" (resultIndex: " + resultIndex + ")");
return result.toString();
}
}