blob: 7c4eed1ef0f87c52dfbca061da23abb5437306d0 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2015, 2017 CEA LIST, Christian W. Damus, 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:
* Onder Gurcan <onder.gurcan@cea.fr> - Initial API and implementation
* Christian W. Damus - bugs 507282, 512666
*
*****************************************************************************/
package org.eclipse.papyrusrt.umlrt.core.types.advice;
import static org.eclipse.papyrusrt.umlrt.core.types.advice.MessageSetEditHelperAdvice.getRelatedCallEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.commands.ConfigureElementCommand;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.infra.services.edit.utils.GMFCommandUtils;
import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes;
import org.eclipse.papyrusrt.umlrt.core.commands.ExcludeRequest;
import org.eclipse.papyrusrt.umlrt.core.types.ElementTypeUtils;
import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil;
import org.eclipse.uml2.uml.CallEvent;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Parameter;
/**
* The helperadvice class used for UMLRealTime::Operation.
*
* @author Onder Gurcan <onder.gurcan@cea.fr>
*
*/
public class OperationAsMessageEditHelperAdvice extends AbstractEditHelperAdvice implements IInheritanceEditHelperAdvice {
private enum Relation {
CHILD, SIBLING, PARENT;
}
@Override
public boolean approveRequest(IEditCommandRequest request) {
if (request instanceof ExcludeRequest) {
return approveExcludeRequest((ExcludeRequest) request);
} else if (request instanceof CreateElementRequest) {
return approveCreateElementRequest((CreateElementRequest) request);
} else {
return super.approveRequest(request);
}
}
/**
* Don't permit exclusion of inherited parameters.
*/
protected boolean approveExcludeRequest(ExcludeRequest request) {
return !(request.getElementToExclude() instanceof Parameter);
}
/**
* Don't permit creation of parameters in an inherited operation.
*/
protected boolean approveCreateElementRequest(CreateElementRequest request) {
return !ElementTypeUtils.isTypeCompatible(request.getElementType(), UMLElementTypes.PARAMETER)
|| !UMLRTExtensionUtil.isInherited((Operation) request.getContainer());
}
@Override
public ICommand getBeforeEditCommand(IEditCommandRequest request) {
ICommand result = getInheritanceEditCommand(request);
if (result == null) {
result = super.getBeforeEditCommand(request);
}
return result;
}
/**
* @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice#getBeforeConfigureCommand(org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest)
*
* @param request
* @return
*/
@Override
protected ICommand getBeforeConfigureCommand(ConfigureRequest request) {
final Operation operation = (Operation) request.getElementToConfigure();
/* @noname final String name = NamedElementUtil.getDefaultNameWithIncrementFromBase("CallEvent", operation.eContainer().eContainer().eContents()); */
final String name = null;
return new ConfigureElementCommand(request) {
private IProgressMonitor progressMonitor;
private IAdaptable info;
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
this.progressMonitor = progressMonitor;
this.info = info;
// Create the UML::CallEvent element
createCallEvent(operation, name);
return CommandResult.newOKCommandResult(operation);
}
/**
* Creates a UML::Usage relation between protocol and rtMessageSet with given name.
*
* @param protocol
* @param name
* @param rtMessageSet
* @throws ExecutionException
*/
private CallEvent createCallEvent(final Operation operation, final String name) throws ExecutionException {
// find the corresponding protocol container
Package protocolContainer = operation.getNearestPackage();
// then create the call event
CallEvent callEvent = (CallEvent) createElement(protocolContainer, name, UMLElementTypes.CALL_EVENT, Relation.CHILD);
// finally associate the operation with this call event
callEvent.setOperation(operation);
return callEvent;
}
/**
*
* @param referenceElement
* @param name
* @param elementType
* @param relation
* @return created element as EObject
* @throws ExecutionException
*/
private EObject createElement(Element referenceElement, String name, IElementType elementType, Relation relation) throws ExecutionException {
if ((referenceElement == null) /* @noname || (name == null) */) {
throw new ExecutionException("Either the referenceElement or the name parameter is null. ");
}
EObject newElement = null;
Package container = referenceElement.getNearestPackage();
CreateElementRequest createElementRequest = new CreateElementRequest(container, elementType);
// get command from edit service
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container);
if (provider == null) {
throw new ExecutionException("Impossible to get the provider from " + container);
}
ICommand createGMFCommand = provider.getEditCommand(createElementRequest);
if (createGMFCommand != null) {
if (createGMFCommand.canExecute()) {
IStatus status = createGMFCommand.execute(progressMonitor, info);
if (status.isOK()) {
newElement = GMFCommandUtils.getCommandEObjectResult(createGMFCommand);
if (newElement == null) {
throw new ExecutionException("Element creation problem for " + elementType.getDisplayName() + ".");
}
// if we do not add this , the default name is set : CallEvent1,2...
// ((NamedElement) newElement).setName(name);
return newElement;
} else {
throw new ExecutionException("Impossible to create the callEvent");
}
} else {
throw new ExecutionException("Command to create the callEvent is not executable");
}
} else {
throw new ExecutionException("Impossible to find a command to create the callEvent");
}
}
};
}
@Override
protected ICommand getBeforeDestroyDependentsCommand(DestroyDependentsRequest request) {
ICommand result = super.getBeforeDestroyDependentsCommand(request);
if (request.getElementToDestroy() instanceof Operation) {
Operation operation = (Operation) request.getElementToDestroy();
CallEvent relatedCallEvent = getRelatedCallEvent(operation.getNearestPackage(), operation);
if (relatedCallEvent != null) {
ICommand command = request.getDestroyDependentCommand(relatedCallEvent);
if (command != null) {
result = (result == null) ? command : result.compose(command);
}
}
}
return result;
}
}