blob: 89602ab642c76361f3d512d80b0c7e1b6d5b606f [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2019 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:
* Xavier Le Pallec (for CEA LIST) xlepallec@lilo.org - Bug 558456
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.js2java;
import java.util.Collection;
import java.util.Map;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.Request;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramCommandStack;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequestFactory;
import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.papyrus.infra.emf.gmf.command.GMFtoEMFCommandWrapper;
import org.eclipse.papyrus.infra.gmfdiag.common.editpart.ResizeableListCompartmentEditPart;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.OperationForClassEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.Activator;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.TypesFactory;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.jsonstructures.JsonUmlOperation;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.jsonstructures.JsonUmlOperationParameter;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.messages.Messages;
import org.eclipse.papyrus.uml.diagram.clazz.providers.UMLElementTypes;
//import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ClassEditPart;
import org.eclipse.papyrus.uml.diagram.common.editparts.ClassEditPart;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
import org.eclipse.uml2.uml.UMLPackage.Literals;
import org.eclipse.uml2.uml.VisibilityKind;
/**
* Instance of this class is dedicated to the creation of commands for editing
* operations. It means
* <UL>
* <LI>creating an operation</LI>
* <LI>updating an operation</LI>
* <LI>deleting an operation</LI>
* </UL>
*
*/
public class JsonUmlOperationToEditPart {
private static final Activator LOGGER = Activator.getDefault();
private TransactionalEditingDomain editingDomain;
private ClassEditPart editPart;
private ResizeableListCompartmentEditPart operationCompartment;
/**
* The constructor needs the editingDomain for the transaction, the class edit
* part and operation compartment edit part.
*
* @param editingDomain
* needed for the transaction
* @param editPart
* needed for the creation of new operation
* @param operationCompartment
* needed for the creation of new operation
*/
public JsonUmlOperationToEditPart(TransactionalEditingDomain editingDomain, ClassEditPart editPart,
ResizeableListCompartmentEditPart operationCompartment) {
super();
this.editingDomain = editingDomain;
this.editPart = editPart;
this.operationCompartment = operationCompartment;
}
/**
* This method creates an operation (notation level) and returns the real
* operation (data level).
*
* @return the real uml operation (data level)
*/
private Operation createVisualOperation() {
try {
GraphicalEditPart parentEditPart = GraphicalEditPart.class.cast(editPart.getParent());
CreateViewRequest requestToCreateAVisualOperation = CreateViewRequestFactory.getCreateShapeRequest(
UMLElementTypes.Operation_ClassOperationLabel, parentEditPart.getDiagramPreferencesHint());
org.eclipse.gef.commands.Command commandToCreateAVisualOperation = operationCompartment
.getCommand(requestToCreateAVisualOperation);
commandToCreateAVisualOperation.execute();
Collection<?> returnValues = DiagramCommandStack.getReturnValues(commandToCreateAVisualOperation);
for (Object returnValue : returnValues) {
if (returnValue instanceof CreateElementRequestAdapter) {
CreateElementRequestAdapter adapter = CreateElementRequestAdapter.class.cast(returnValue);
if (adapter.resolve() instanceof Operation) {
return Operation.class.cast(adapter.resolve());
}
}
}
} catch (Exception ex) {
LOGGER.logError(ex.toString(), ex);
}
return null;
}
/**
* This method returns the command for creating an operation based on a textual
* definition (UmlOperation). The method just uses commandForUpdatingOperation
* but with an empty operation that it creates.
*
* @param operation
* textual definition of the operation
* @return the creation command.
*/
protected Command commandForAddingOperation(JsonUmlOperation operation) {
return commandForUpdatingOperation(operation, null);
}
/**
* This method returns the command for updating an existing operation based on a
* textual definition (UmlOperation).
*
* @param operation
* textual definition of the operation
* @param concretePapyrusOperation
* the existing and real operation (data level).
* @return the updating command
*/
protected Command commandForUpdatingOperation(JsonUmlOperation operation, Operation papyrusOperation) {
return new RecordingCommand(editingDomain,
(papyrusOperation == null ? Messages.JsonUmlOperationToEditPart_Add_TitleCommand : Messages.JsonUmlOperationToEditPart_Update_TitleCommand) + operation.getName()) {
@Override
protected void doExecute() {
Operation concretePapyrusOperation = papyrusOperation;
concretePapyrusOperation = createOperationIfNull(concretePapyrusOperation);
processNameProperty(operation, concretePapyrusOperation);
processVisibilityProperty(operation, concretePapyrusOperation);
while (!concretePapyrusOperation.getOwnedParameters().isEmpty()) {
destroyParameter(concretePapyrusOperation.getOwnedParameters().get(0));
}
for (JsonUmlOperationParameter parameter : operation.getParameters()) {
// I did not found UMLElementTypes for parameter in order to use
// CreateElementRequest
Parameter papyrusParameter = concretePapyrusOperation.createOwnedParameter(parameter.getName(),
TypesFactory.getInstance().createTypeHelper(concretePapyrusOperation)
.getTypeFromName(parameter.getType()));
// Multiplicity - Lower
papyrusParameter.setLower(parameter.getLower());
// Multiplicity - Upper
papyrusParameter.setUpper(parameter.getUpper());
// Direction
papyrusParameter.setDirection(ParameterDirectionKind.get(parameter.getDirection()));
// Ordered
papyrusParameter.setIsOrdered(parameter.isOrdered());
// Unique
papyrusParameter.setIsUnique(parameter.isUnique());
// Sequence - not found
}
}
};
}
/**
* This method is for constructing a command that removes an operation (data
* level) from a class
*
* @param operationEditParts
* the list of operations of the class
* @param papyrusOperation
* the real operation
* @return the removing command
*/
protected Command commandForRemovingOperation(Map<String, OperationForClassEditPart> operationEditParts,
Operation papyrusOperation) {
return new RecordingCommand(editingDomain, Messages.JsonUmlOperationToEditPart_Remove_TitleCommand + papyrusOperation.getName()) {
@Override
protected void doExecute() {
try {
OperationForClassEditPart operationEditPart = operationEditParts.get(papyrusOperation.getName());
Request deleteViewRequest = new EditCommandRequestWrapper(new DestroyElementRequest(false));
org.eclipse.gef.commands.Command command2 = operationEditPart.getCommand(deleteViewRequest);
operationEditPart.getDiagramEditDomain().getDiagramCommandStack().execute(command2);
} catch (Exception ex) {
LOGGER.logError(ex.toString(), ex);
}
}
};
}
private Command createSetCommand(SetRequest setRequest, Operation papyrusOperation) {
IElementEditService commandProvider = ElementEditServiceUtils.getCommandProvider(papyrusOperation);
ICommand setCommand = commandProvider.getEditCommand(setRequest);
return new GMFtoEMFCommandWrapper(setCommand);
}
private Operation createOperationIfNull(Operation papyrusOperation) {
if (papyrusOperation == null) {
papyrusOperation = createVisualOperation();
}
return papyrusOperation;
}
private void processNameProperty(JsonUmlOperation operation, Operation papyrusOperation) {
if (!papyrusOperation.getName().equals(operation.getName())) {
createSetCommand(new SetRequest(papyrusOperation, Literals.NAMED_ELEMENT__NAME, operation.getName()),
papyrusOperation).execute();
}
}
private void processVisibilityProperty(JsonUmlOperation operation, Operation papyrusOperation) {
VisibilityKind visibility = VisibilityKind.get(operation.getVisibility());
if (!papyrusOperation.getVisibility().equals(visibility)) {
createSetCommand(
new SetRequest(papyrusOperation, Literals.NAMED_ELEMENT__VISIBILITY, operation.getVisibility()),
papyrusOperation).execute();
}
}
private void destroyParameter(Parameter parameterToDestroy) {
DestroyElementRequest destroyRequest = new DestroyElementRequest(parameterToDestroy, false);
IElementEditService commandProvider = ElementEditServiceUtils.getCommandProvider(parameterToDestroy);
ICommand destroyCommand = commandProvider.getEditCommand(destroyRequest);
new GMFtoEMFCommandWrapper(destroyCommand).execute();
}
}