blob: fc9737e1dd5ccb4fd362b1846f9eedb8324626f3 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2002-2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*
* </copyright>
*
* $Id: AbstractCommand.java,v 1.1 2005/04/15 23:31:25 david_williams Exp $
*/
package org.eclipse.emf.common.command;
import java.util.Collection;
import java.util.Collections;
/**
* An abstract implementation of a basic command. Each derived class
* <bold>must</bold> implement {@link Command#execute} and
* {@link Command#redo}, <bold>must</bold> either implement {@link #undo} or
* implement {@link #canUndo} to return false, and <bold>must</bold> either
* override {@link #prepare} (this is the preferred approach) or can override
* {@link #canExecute} directly.
*
* <p>
* It is very convenient to use prepare, as it is guaranteed to be called only
* once just before canExecute is to be tested. It can be implemented to
* create any additional commands that need to be executed, and the result it
* yields becomes the permanent cached return value for canExecute.
*
*/
public abstract class AbstractCommand implements Command {
/**
* Keeps track of whether prepare needs to be called. It is tested in
* {@link #canExecute} so that {@link #prepare} is called exactly once to
* ready the command for execution.
*/
protected boolean isPrepared;
/**
* Keeps track of whether the command is executable. It is set in
* {@link #canExecute} to the result of calling {@link #prepare}.
*/
protected boolean isExecutable;
/**
* Holds a short textual description of the command as returned by
* {@link #getDescription} and set by {@link #setDescription}.
*/
protected String description;
/**
* Holds the label of the command as returned by {@link #getLabel} and set
* by {@link #setLabel}.
*/
protected String label;
/**
* Creates an empty instance.
*/
protected AbstractCommand() {
}
/**
* Creates an instance with the given label.
*
* @param label
* the label.
*/
protected AbstractCommand(String label) {
this.label = label;
}
/**
* Creates and instance with the given label and description.
*
* @param label
* the label.
* @param description
* the description.
*/
protected AbstractCommand(String label, String description) {
this.label = label;
this.description = description;
}
/**
* Called at most once in {@link #canExecute} to give the command an
* opportunity to ready itself for execution. The returned value is stored
* in {@link #canExecute}. In other words, you can override this method
* to initialize and to yield a cached value for the all subsequent calls
* to canExecute.
*
* @return whether the command is executable.
*/
protected boolean prepare() {
return false;
}
/**
* Calls {@link #prepare}, caches the result in {@link #isExecutable},
* and sets {@link #isPrepared} to <code>true</code>; from then on, it
* will yield the value of isExecutable.
*
* @return whether the command can execute.
*/
public boolean canExecute() {
if (!isPrepared) {
isExecutable = prepare();
isPrepared = true;
}
return isExecutable;
}
/**
* Returns <code>true</code> because most command should be undoable.
*
* @return <code>true</code>.
*/
public boolean canUndo() {
return true;
}
/**
* Throws a runtime exception.
*
* @exception UnsupportedOperationException
* always.
*/
public void undo() {
throw new RuntimeException("_EXC_Method_not_implemented");
}
/**
* Returns an empty list.
*
* @return an empty list.
*/
public Collection getResult() {
return Collections.EMPTY_LIST;
}
/**
* Returns an empty list.
*
* @return an empty list.
*/
public Collection getAffectedObjects() {
return Collections.EMPTY_LIST;
}
/*
* Javadoc copied from interface.
*/
public String getLabel() {
return label == null ? "_UI_AbstractCommand_label" : label;
}
/**
* Sets the label after construction.
*
* @param label
* the new label.
*/
public void setLabel(String label) {
this.label = label;
}
/*
* Javadoc copied from interface.
*/
public String getDescription() {
return description == null ? "_UI_AbstractCommand_description" : description;
}
/**
* Sets the description after construction.
*
* @param description
* the new description.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Creates a new compound command, containing this command and the given
* command, that delegates chain to {@link CompoundCommand#append}.
*
* @param command
* the command to chain with this one.
* @return a new chained compound command.
*/
public Command chain(Command command) {
class ChainedCompoundCommand extends CompoundCommand {
public ChainedCompoundCommand() {
}
public Command chain(Command c) {
append(c);
return this;
}
}
CompoundCommand result = new ChainedCompoundCommand();
result.append(this);
result.append(command);
return result;
}
/*
* Javadoc copied from interface.
*/
public void dispose() {
}
/**
* Returns an abbreviated name using this object's own class' name,
* without package qualification, followed by a space separated list of
* <tt>field:value</tt> pairs.
*
* @return string representation.
*/
public String toString() {
String className = getClass().getName();
int lastDotIndex = className.lastIndexOf('.');
StringBuffer result = new StringBuffer(lastDotIndex == -1 ? className : className.substring(lastDotIndex + 1));
result.append(" (label: " + label + ")");
result.append(" (description: " + description + ")");
result.append(" (isPrepared: " + isPrepared + ")");
result.append(" (isExecutable: " + isExecutable + ")");
return result.toString();
}
/**
* A marker interface implemented by commands that don't dirty the model.
*/
public static interface NonDirtying {
}
}