blob: c759b8e97d37d63d37e63b17b1a83909a5776bfd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2005 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
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.j2ee.internal.webservice.command;
import java.util.Collection;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
public class CommandSetElement extends AbstractCommand {
private EObject parent_;
private EStructuralFeature childFeature_;
private Object newChild_;
private Object oldChild_;
private boolean oldChildSet_;
public CommandSetElement(String label, String description, EObject parent, EStructuralFeature childFeature, Object newChild) {
this(label, description, parent, childFeature, newChild, null);
}
public CommandSetElement(String label, String description, EObject parent, EStructuralFeature childFeature, Object newChild, Object oldChild) {
super(label, description);
parent_ = parent;
childFeature_ = childFeature;
newChild_ = newChild;
oldChild_ = oldChild;
oldChildSet_ = true;
}
/**
* 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.
*/
@Override
protected boolean prepare() {
return true;
}
/**
* Returns whether the comamad is valid to <code>execute</code>. The
* { @link UnexecutableCommand#INSTANCE}.<code>canExecute()</code> always returns
* <code>false</code>. This <b>must </b> be called before calling <code>execute</code>.
*
* @return whether the comamad is valid to <code>execute</code>.
*/
@Override
public boolean canExecute() {
return super.canExecute();
}
/**
* Performs the command activity required for the effect. The effect of calling
* <code>execute</code> when <code>canExecute</code> returns <code>false</code>, or when
* <code>canExecute</code> hasn't been called, is undefined.
*/
public void execute() {
if (childFeature_.isMany() && !(newChild_ instanceof EList)) {
if (oldChild_ != null && newChild_ != null) {
EList eList = (EList) parent_.eGet(childFeature_);
int index = eList.indexOf(oldChild_);
if (index != -1)
eList.set(index, newChild_);
}
} else {
oldChild_ = parent_.eGet(childFeature_);
oldChildSet_ = parent_.eIsSet(childFeature_);
if (newChild_ != null)
parent_.eSet(childFeature_, newChild_);
else
parent_.eUnset(childFeature_);
}
}
/**
* Returns <code>true</code> because most command should be undoable.
*
* @return <code>true</code>.
*/
@Override
public boolean canUndo() {
return true;
}
/**
* Performs the command activity required to <code>undo</code> the effects of a preceding
* <code>execute</code> (or <code>redo</code>). The effect, if any, of calling
* <code>undo</code> before <code>execute</code> or <code>redo</code> have been called, or
* when canUndo returns <code>false</code>, is undefined.
*/
@Override
public void undo() {
if (childFeature_.isMany() && !(newChild_ instanceof EList)) {
if (oldChild_ != null && newChild_ != null) {
EList eList = (EList) parent_.eGet(childFeature_);
int index = eList.indexOf(newChild_);
if (index != -1)
eList.set(index, oldChild_);
}
} else {
if (oldChildSet_)
parent_.eSet(childFeature_, oldChild_);
else
parent_.eUnset(childFeature_);
}
}
/**
* Performs the command activity required to <code>redo</code> the effect after undoing the
* effect. The effect, if any, of calling <code>redo</code> before <code>undo</code> is
* called is undefined. Note that if you implement <code>redo</code> to call
* <code>execute</code> then any derived class will be restricted by that decision also.
*/
public void redo() {
execute();
}
/**
* Returns a collection of things which this command wishes to present as it's result. The
* result of calling this before an <code>execute</code> or <code>redo</code>, or after an
* <code>undo</code>, is undefined.
*
* @return a collection of things which this command wishes to present as it's result.
*/
@Override
public Collection getResult() {
return super.getResult();
}
/**
* Returns the collection of things which this command wishes to present as the objects affected
* by the command. Typically should could be used as the selection that should be highlighted to
* best illustrate the effect of the command. The result of calling this before an
* <code>execute</code>,<code>redo</code>, or <code>undo</code> is undefined. The
* result may be different after an <code>undo</code> than it is after an <code>execute</code>
* or <code>redo</code>, but the result should be the same (equivalent) after either an
* <code>execute</code> or <code>redo</code>.
*
* @return the collection of things which this command wishes to present as the objects affected
* by the command.
*/
@Override
public Collection getAffectedObjects() {
return super.getAffectedObjects();
}
/**
* Called to indicate that the command will never be used again. Calling any other method after
* this one has undefined results.
*/
@Override
public void dispose() {
//Do nothing
}
/**
* Returns a command that represents the composition of this command with the given command. The
* resulting command may just be this, if this command is capabable of composition. Otherwise,
* it will be a new command created to compose the two.
* <p>
* Instead of the following pattern of usage
*
* <pre>
* Command result = x;
* if (condition)
* result = result.chain(y);
* </pre>
*
* you should consider using a {@link org.eclipse.emf.common.command.CompoundCommand}and using
* { @link org.eclipse.emf.common.command.CompoundCommand#unwrap()}to optimize the result:
*
* <pre>
* CompoundCommand subcommands = new CompoundCommand();
* subcommands.append(x);
* if (condition)
* subcommands.append(y);
* Command result = subcommands.unwrap();
* </pre>
*
* This gives you more control over how the compound command composes it's result and affected
* objects.
*
* @param command
* the command to chain.
* @return a command that represents the composition of this command with the given command.
*/
@Override
public Command chain(Command command) {
return super.chain(command);
}
}