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