blob: 92e77cf0ae94aa26c5d9899dd495e447ef8babcc [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2009 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 Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.diagram.ui.commands;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.common.core.command.AbstractCommand;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.common.core.util.StringStatics;
import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramCommandStack;
/**
* A Wrapper around a real element creation command
* The main use of this command is to ensure that the semantic
* adapter is updated appropriately upon undo and redo of the real command
*
* @author melaasar
*/
public class SemanticCreateCommand extends AbstractCommand {
/** the request adapter */
CreateElementRequestAdapter requestAdapter;
/** the real element creation command */
private ICommand realSemanticCommand;
/**
* Creates a new semantic create command that wraps around a real command
* @param requestAdapter
* @param realSemanticCommand
*/
public SemanticCreateCommand(
CreateElementRequestAdapter requestAdapter,
Command realSemanticCommand) {
super((realSemanticCommand.getLabel() == null) ? StringStatics.BLANK : realSemanticCommand.getLabel(), null);
Assert.isNotNull(requestAdapter);
Assert.isNotNull(realSemanticCommand);
this.requestAdapter = requestAdapter;
this.realSemanticCommand =
DiagramCommandStack.getICommand(realSemanticCommand);
// propagate the contexts from the wrapped command
recomputeContexts();
}
/**
* If the command was properly executed, the result will be set during
* execution. If the command failed execution, the result may contain status
* information for feedback purposes.
*
* @return
* The command result either from this command executed
* properly or the wrapped realSemanticCommand in case status information
* needs to be returned.
*/
@Override
public CommandResult getCommandResult() {
CommandResult result = super.getCommandResult();
if (result == null) {
return realSemanticCommand.getCommandResult();
}
return result;
}
protected CommandResult doExecuteWithResult(
IProgressMonitor progressMonitor, IAdaptable info)
throws ExecutionException {
realSemanticCommand.execute(progressMonitor, info);
CommandResult result = realSemanticCommand.getCommandResult();
if (result.getStatus().isOK()) {
Object object = result.getReturnValue();
if (object instanceof Collection) {
Collection col = (Collection) object;
object = col.isEmpty() ? null : col.iterator().next();
}
if (object != null) {
Assert.isTrue(object instanceof EObject, "Failed to get an IElement out of the semantic command returned value");//$NON-NLS-1$
EObject element = (EObject) object;
requestAdapter.setNewElement(element);
}
result = CommandResult.newOKCommandResult(requestAdapter);
}
recomputeContexts();
return result;
}
protected CommandResult doRedoWithResult(IProgressMonitor progressMonitor, IAdaptable info)
throws ExecutionException {
realSemanticCommand.redo(progressMonitor, info);
CommandResult result = realSemanticCommand.getCommandResult();
recomputeContexts();
return result;
}
protected CommandResult doUndoWithResult(IProgressMonitor progressMonitor, IAdaptable info)
throws ExecutionException {
realSemanticCommand.undo(progressMonitor, info);
CommandResult result = realSemanticCommand.getCommandResult();
recomputeContexts();
return result;
}
public boolean canExecute() {
return realSemanticCommand.canExecute();
}
public boolean canUndo() {
return realSemanticCommand.canUndo();
}
public boolean canRedo() {
return realSemanticCommand.canRedo();
}
public List getAffectedFiles() {
return realSemanticCommand.getAffectedFiles();
}
/**
* Propagates the contexts from my wrapped command.
*/
private void recomputeContexts() {
// Get my real contexts from my wrapped command
IUndoContext[] realContexts = realSemanticCommand.getContexts();
// Clear my contexts
IUndoContext[] myContexts = getContexts();
for (int i = 0; i < myContexts.length; i++) {
removeContext(myContexts[i]);
}
// Add the contexts from my wrapped command
for (int i = 0; i < realContexts.length; i++) {
addContext(realContexts[i]);
}
}
/**
* Adds the context to my wrapped command.
*/
public void addContext(IUndoContext context) {
super.addContext(context);
realSemanticCommand.addContext(context);
}
/**
* Removes the context from my wrapped command.
*/
public void removeContext(IUndoContext context) {
super.removeContext(context);
realSemanticCommand.removeContext(context);
}
public void dispose() {
super.dispose();
realSemanticCommand.dispose();
}
}