/******************************************************************************* * 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); } }