/*****************************************************************************
* Copyright (c) 2010 Atos Origin.
*
*
* 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:
* Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.usecase.command;
import org.eclipse.core.commands.ExecutionException;
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.gef.commands.CompoundCommand;
import org.eclipse.gef.editparts.AbstractEditPart;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.papyrus.infra.core.utils.EditorUtils;
import org.eclipse.papyrus.uml.diagram.usecase.edit.commands.ExtensionPointCreateCommand;
import org.eclipse.papyrus.uml.diagram.usecase.edit.parts.ExtensionPointEditPart;
import org.eclipse.papyrus.uml.diagram.usecase.edit.parts.UseCasePointsEditPartTN;
import org.eclipse.papyrus.uml.diagram.usecase.edit.parts.UseCasePointsInComponentEditPart;
import org.eclipse.papyrus.uml.diagram.usecase.edit.parts.UseCasePointsInPackageEditPart;
import org.eclipse.papyrus.uml.diagram.usecase.providers.UMLElementTypes;
import org.eclipse.uml2.uml.Extend;
import org.eclipse.uml2.uml.ExtensionPoint;
import org.eclipse.uml2.uml.UseCase;
public class CreateExtensionPointCommand extends Command {
/** The command to create the extension point */
private ICommandProxy elementCreationCommand = null;
/** The command to create corresponding view */
private CompoundCommand viewsCreationCommand = null;
/** The command to set the property extension point in extend element */
private ICommandProxy setExtensionPropertyCmd;
/** The compartment which graphically contains the extension point to create */
private AbstractEditPart compartment = null;
/** The e object container of the extension point */
private EObject containerObject;
/** the element type */
private IHintedType type;
/** adapter to get the extend element */
private IAdaptable adapter;
public CreateExtensionPointCommand(IHintedType elementType, AbstractEditPart compartmentPart, EObject container, IAdaptable adapter) {
elementCreationCommand = getElementCreationCommand(container, elementType);
type = elementType;
compartment = compartmentPart;
containerObject = container;
this.adapter = adapter;
}
/**
* Get the Command to create the extension point element
*
* @param container
* the use case which owns the extension point
* @param elementType
* the type of the extension point
* @return the command to create model element or null
*/
private static ICommandProxy getElementCreationCommand(EObject container, IHintedType elementType) {
CreateElementRequest createElementReq = new CreateElementRequest(container, elementType);
if(UMLElementTypes.ExtensionPoint_3007.equals(elementType)) {
ExtensionPointCreateCommand cmd = new ExtensionPointCreateCommand(createElementReq);
return new ICommandProxy(cmd);
} else {
return null;
}
}
/**
* Get the Command to create the extension point element
*
* @param container
* the use case which owns the extension point
* @param elementType
* the type of the extension point
* @return the command to create model element or null
*/
private ICommandProxy getExtensionPointAddCommand(Extend extend, ExtensionPoint extPoint) {
SetExtensionPropertyCmd cmd = new SetExtensionPropertyCmd(extend, extPoint);
return new ICommandProxy(cmd);
}
/**
* @see org.eclipse.gef.commands.Command#canExecute()
*/
@Override
public boolean canExecute() {
return elementCreationCommand != null && elementCreationCommand.canExecute();
}
/**
* Execute the command : create the model element, then the corresponding view
*
* @see org.eclipse.gef.commands.Command#execute()
*/
@Override
public void execute() {
super.execute();
Object extensionPoint = getExtensionPoint();
// create the view for the extension point
if(extensionPoint instanceof ExtensionPoint && compartment != null && type != null) {
// set the property of extend element with the extension point
Object object = adapter.getAdapter(Extend.class);
if(object instanceof Extend) {
Extend extend = (Extend)object;
setExtensionPropertyCmd = getExtensionPointAddCommand(extend, (ExtensionPoint)extensionPoint);
if(setExtensionPropertyCmd.canExecute()) {
setExtensionPropertyCmd.execute();
}
}
createExtensionPointView((ExtensionPoint)extensionPoint);
}
}
/**
* @return the first extension point if exists, create a new one any
*/
private Object getExtensionPoint() {
Object extensionPoint = null;
if(containerObject instanceof UseCase) {
UseCase useCase = (UseCase)containerObject;
if(useCase.getExtensionPoints() != null && !useCase.getExtensionPoints().isEmpty()) {
extensionPoint = useCase.getExtensionPoints().get(0);
}
}
// or create a new extension point if needed
if(elementCreationCommand != null && extensionPoint == null) {
elementCreationCommand.execute();
extensionPoint = elementCreationCommand.getICommand().getCommandResult().getReturnValue();
}
return extensionPoint;
}
/**
* Creates the extension point view if needed
*
* @param extensionPoint
* the extension point element
*/
private void createExtensionPointView(ExtensionPoint extensionPoint) {
viewsCreationCommand = new CompoundCommand();
IGraphicalEditPart useCasePointEP = null;
for(Object ep : compartment.getChildren()) {
if(ep instanceof UseCasePointsEditPartTN) {
useCasePointEP = (IGraphicalEditPart)ep;
break;
} else if(ep instanceof UseCasePointsInComponentEditPart) {
useCasePointEP = (IGraphicalEditPart)ep;
break;
} else if(ep instanceof UseCasePointsInPackageEditPart) {
useCasePointEP = (IGraphicalEditPart)ep;
break;
}
}
if(useCasePointEP != null) {
// check if extension point is already drawn
boolean alreadyDrawn = false;
for(Object obj : useCasePointEP.getChildren()) {
if((obj instanceof ExtensionPointEditPart) && extensionPoint.equals(((ExtensionPointEditPart)obj).resolveSemanticElement())) {
alreadyDrawn = true;
break;
}
}
if(!alreadyDrawn) {
ViewDescriptor descriptor = new CreateViewRequest.ViewDescriptor(new EObjectAdapter((EObject)extensionPoint), Node.class, type.getSemanticHint(), useCasePointEP.getDiagramPreferencesHint());
CreateViewRequest request = new CreateViewRequest(descriptor);
Command nodeCreationCommand = useCasePointEP.getCommand(request);
viewsCreationCommand.add(nodeCreationCommand);
viewsCreationCommand.execute();
}
}
}
/**
* Undo model and views creation
*
* @see org.eclipse.gef.commands.Command#undo()
*/
@Override
public void undo() {
if(viewsCreationCommand != null) {
viewsCreationCommand.undo();
}
if(setExtensionPropertyCmd != null) {
setExtensionPropertyCmd.undo();
}
if(elementCreationCommand != null) {
elementCreationCommand.undo();
}
}
/**
* Custom command to set the property extension points in extend element
*/
private class SetExtensionPropertyCmd extends AbstractTransactionalCommand {
private ExtensionPoint extPoint;
private Extend extend;
public SetExtensionPropertyCmd(Extend extend, ExtensionPoint extensionPoint) {
super(EditorUtils.getTransactionalEditingDomain(), "Set extension point property", null);
this.extend = extend;
this.extPoint = extensionPoint;
}
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
extend.getExtensionLocations().add(extPoint);
return CommandResult.newOKCommandResult();
}
}
}