blob: 01f3ec1faed0eec420943210bee08dc826d357ae [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2020 CEA LIST
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ansgar.radermacher@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.robotics.core.types.advice;
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.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
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.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.DestroyElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.GetEditContextRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.robotics.core.types.RoboticElementTypesEnumerator;
import org.eclipse.papyrus.robotics.core.utils.NamingUtil;
import org.eclipse.papyrus.robotics.profile.robotics.components.ComponentDefinition;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.util.UMLUtil;
/**
* Create additional activityInstance, when an activity get created.
*/
public class ActivityEditHelperAdvice extends AbstractEditHelperAdvice {
/**
* Allow creation only if container is a component definition
*/
protected boolean approveCreateElementRequest(CreateElementRequest request) {
IElementType type = request.getElementType();
EObject container = request.getContainer();
if (type != null && container instanceof Class) {
if (StereotypeUtil.isApplied((Class) container, ComponentDefinition.class)) {
return true;
}
}
return false;
}
@Override
public boolean approveRequest(IEditCommandRequest request) {
if (request instanceof GetEditContextRequest) {
GetEditContextRequest context = (GetEditContextRequest) request;
if (context.getEditCommandRequest() instanceof CreateElementRequest) {
return approveCreateElementRequest((CreateElementRequest) context.getEditCommandRequest());
}
}
return super.approveRequest(request);
}
/**
* @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice#getAfterConfigureCommand(ogrg.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest)
*
* Add data-type.
*/
@Override
protected ICommand getAfterConfigureCommand(ConfigureRequest request) {
// Get element from the request
EObject newElement = request.getElementToConfigure();
// Check it is a kind of Class
if (!(newElement instanceof Class)) {
// Activator.log.debug("");
return super.getAfterConfigureCommand(request);
}
Class activity = (Class) newElement;
// Check it is a nested Classifier of a ComponentDefinition
Element eClsOwner = activity.getOwner();
if (!(eClsOwner instanceof Class && StereotypeUtil.isApplied(eClsOwner, ComponentDefinition.class))) {
return super.getAfterConfigureCommand(request);
}
Class component = (Class) eClsOwner;
CompositeCommand compositeCommand = new CompositeCommand("Configure activity command"); //$NON-NLS-1$
final IElementEditService commandProvider = ElementEditServiceUtils.getCommandProvider(component);
CreateElementRequest createActInstReq = new CreateElementRequest(component, RoboticElementTypesEnumerator.ACTIVITY_INSTANCE);
ICommand createActInstCmd = commandProvider.getEditCommand(createActInstReq);
@SuppressWarnings("nls")
SetRequest setActivityNameReq = new SetRequest(activity, UMLPackage.eINSTANCE.getNamedElement_Name(),
NamingUtil.getName(activity, "Activity", "%02d"));
ICommand setActivityNameCmd = commandProvider.getEditCommand(setActivityNameReq);
// execute rest of command (after having obtained the command result), notably
// naming the activityInstance and setting its type
ICommand wrapper = new CompositeCommand("wrapper") { //$NON-NLS-1$
boolean first = true;
@Override
public boolean canExecute() {
if (first) {
return true;
}
return super.canExecute();
}
@Override
public IStatus execute(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
if (first) {
Object result = createActInstCmd.getCommandResult().getReturnValue();
if (result instanceof Property) {
Property activityInst = (Property) result;
SetRequest setInstNameReq = new SetRequest(activityInst, UMLPackage.eINSTANCE.getNamedElement_Name(),
activity.getName().toLowerCase());
ICommand setInstNameCmd = commandProvider.getEditCommand(setInstNameReq);
add(setInstNameCmd);
SetRequest setInstTypeReq = new SetRequest(activityInst, UMLPackage.eINSTANCE.getTypedElement_Type(), activity);
ICommand setInstTypeCmd = commandProvider.getEditCommand(setInstTypeReq);
add(setInstTypeCmd);
}
first = false;
}
return super.execute(progressMonitor, info);
}
};
compositeCommand.add(createActInstCmd);
compositeCommand.add(setActivityNameCmd);
compositeCommand.add(wrapper);
return compositeCommand.isEmpty() ? super.getAfterConfigureCommand(request) : compositeCommand;
}
/**
* Remove created activityInstance, if activity is destroyed
*/
@Override
protected ICommand getAfterDestroyDependentsCommand(DestroyDependentsRequest request) {
CompositeCommand compositeCommand = new CompositeCommand("activity instance destruction command"); //$NON-NLS-1$
EObject destroyElement = request.getElementToDestroy();
if (!(destroyElement instanceof Class)) {
return super.getAfterDestroyDependentsCommand(request);
}
final Class cls = (Class) destroyElement;
final IElementEditService commandProvider = ElementEditServiceUtils.getCommandProvider(cls);
for (Setting setting : UMLUtil.getNonNavigableInverseReferences(cls)) {
EObject propertyCandidate = setting.getEObject();
if (propertyCandidate instanceof Property) {
DestroyElementRequest destroyDepReq = new DestroyElementRequest(propertyCandidate, false);
ICommand destroyDepCmd = commandProvider.getEditCommand(destroyDepReq);
compositeCommand.add(destroyDepCmd);
}
}
return compositeCommand.isEmpty() ? super.getAfterDestroyDependentsCommand(request) : compositeCommand;
}
}