/*******************************************************************************
* 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 execute
. The
* { @link UnexecutableCommand#INSTANCE}.canExecute()
always returns
* false
. This must be called before calling execute
.
*
* @return whether the comamad is valid to execute
.
*/
@Override
public boolean canExecute() {
return super.canExecute();
}
/**
* Performs the command activity required for the effect. The effect of calling
* execute
when canExecute
returns false
, or when
* canExecute
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 true
because most command should be undoable.
*
* @return true
.
*/
@Override
public boolean canUndo() {
return true;
}
/**
* Performs the command activity required to undo
the effects of a preceding
* execute
(or redo
). The effect, if any, of calling
* undo
before execute
or redo
have been called, or
* when canUndo returns false
, 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 redo
the effect after undoing the
* effect. The effect, if any, of calling redo
before undo
is
* called is undefined. Note that if you implement redo
to call
* execute
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 execute
or redo
, or after an
* undo
, 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
* execute
,redo
, or undo
is undefined. The
* result may be different after an undo
than it is after an execute
* or redo
, but the result should be the same (equivalent) after either an
* execute
or redo
.
*
* @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.
*
* Instead of the following pattern of usage * *
* Command result = x; * if (condition) * result = result.chain(y); ** * 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: * *
* CompoundCommand subcommands = new CompoundCommand(); * subcommands.append(x); * if (condition) * subcommands.append(y); * Command result = subcommands.unwrap(); ** * 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); } }