diff options
Diffstat (limited to 'plugins/toolsmiths/org.eclipse.papyrus.def/xtend/aspects/xpt/diagram/editpolicies/BaseItemSemanticEditPolicy.xtend')
-rw-r--r-- | plugins/toolsmiths/org.eclipse.papyrus.def/xtend/aspects/xpt/diagram/editpolicies/BaseItemSemanticEditPolicy.xtend | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/plugins/toolsmiths/org.eclipse.papyrus.def/xtend/aspects/xpt/diagram/editpolicies/BaseItemSemanticEditPolicy.xtend b/plugins/toolsmiths/org.eclipse.papyrus.def/xtend/aspects/xpt/diagram/editpolicies/BaseItemSemanticEditPolicy.xtend new file mode 100644 index 00000000000..e211ac08408 --- /dev/null +++ b/plugins/toolsmiths/org.eclipse.papyrus.def/xtend/aspects/xpt/diagram/editpolicies/BaseItemSemanticEditPolicy.xtend @@ -0,0 +1,387 @@ +/** + * Copyright (c) 2007, 2014 Borland Software Corporation, 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: + * Alexander Shatalin (Borland) - initial API and implementation + * Michael Golubev (Montages) - #386838 - migrate to Xtend2 + * Christian W. Damus - bug 451230 + */ +package aspects.xpt.diagram.editpolicies + +import aspects.xpt.Common +import com.google.inject.Inject +import com.google.inject.Singleton +import metamodel.MetaModel +import org.eclipse.emf.codegen.ecore.genmodel.GenClass +import org.eclipse.emf.codegen.ecore.genmodel.GenFeature +import org.eclipse.gmf.codegen.gmfgen.GenDiagram +import org.eclipse.gmf.codegen.gmfgen.GenLink +import org.eclipse.gmf.codegen.gmfgen.TypeLinkModelFacet +import org.eclipse.papyrus.papyrusgmfgenextension.GenerateUsingElementTypeCreationCommand +import plugin.Activator +import xpt.OclMigrationProblems_qvto +import xpt.editor.VisualIDRegistry +import xpt.providers.ElementTypes + +//Documentation: PapyrusGenCode +//This tamplate has been modified in order to allow the moving command +@Singleton class BaseItemSemanticEditPolicy extends xpt.diagram.editpolicies.BaseItemSemanticEditPolicy { + @Inject extension Common; + @Inject Activator xptPluginActivator; + @Inject extension VisualIDRegistry + @Inject ElementTypes xptElementTypes; + @Inject extension OclMigrationProblems_qvto; + @Inject extension xpt.diagram.editpolicies.Utils_qvto + @Inject MetaModel xptMetaModel; + + override BaseItemSemanticEditPolicy(GenDiagram it) ''' +«copyright(editorGen)» +package «packageName(it)»; + +«generatedClassComment()» +public class «className(it)» extends org.eclipse.gmf.runtime.diagram.ui.editpolicies.SemanticEditPolicy { + + «attributes(it)» + + «constructor(it)» + + «generatedMemberComment( + 'Extended request data key to hold editpart visual id.\n' + 'Add visual id of edited editpart to extended data of the request\n' + 'so command switch can decide what kind of diagram element is being edited.\n' + 'It is done in those cases when it\'s not possible to deduce diagram\n' + 'element kind from domain element.\n' + 'Add the reoriented view to the request extended data so that the view\n ' + 'currently edited can be distinguished from other views of the same element\n ' + + 'and these latter possibly removed if they become inconsistent after reconnect\n' + )» + @SuppressWarnings("unchecked") + public org.eclipse.gef.commands.Command getCommand(org.eclipse.gef.Request request) { + if (request instanceof org.eclipse.gef.requests.ReconnectRequest) { + Object view = ((org.eclipse.gef.requests.ReconnectRequest) request).getConnectionEditPart().getModel(); + if (view instanceof org.eclipse.gmf.runtime.notation.View) { + String id = «getVisualIDMethodCall(it)»((org.eclipse.gmf.runtime.notation.View) view); + request.getExtendedData().put(VISUAL_ID_KEY, id); + request.getExtendedData().put(GRAPHICAL_RECONNECTED_EDGE, view); + } + } + return super.getCommand(request); + } + + «generatedMemberComment('Returns visual id from request parameters.')» + protected String getVisualID(org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest request) { + return (String) request.getParameter(VISUAL_ID_KEY); + } + + «semanticPart(it)» + + «generatedMemberComment('Returns editing domain from the host edit part.')» + protected org.eclipse.emf.transaction.TransactionalEditingDomain getEditingDomain() { + return ((org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) getHost()).getEditingDomain(); + } + + «addDestroyShortcutsCommand(it)» + +«IF links.exists(link|!link.sansDomain)» + «linkConstraints(it)» +«ENDIF» + + «additions(it)» +} +''' + +override def addDestroyShortcutsCommand(GenDiagram it) ''' + «generatedMemberComment('Clean all shortcuts to the host element from the same diagram')» + protected void addDestroyShortcutsCommand(org.eclipse.gmf.runtime.common.core.command.ICompositeCommand cmd, org.eclipse.gmf.runtime.notation.View view) { + «_assert('view.getEAnnotation(\"Shortcut\") == null')» + for (java.util.Iterator<?> it = view.getDiagram().getChildren().iterator(); it.hasNext();) { + org.eclipse.gmf.runtime.notation.View nextView = (org.eclipse.gmf.runtime.notation.View) it.next(); + if (nextView.getEAnnotation("Shortcut") == null || !nextView.isSetElement() || nextView.getElement() != view.getElement()) { «nonNLS()» + continue; + } + cmd.add(new org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand(getEditingDomain(), nextView)); + } + } +''' + + override attributes(GenDiagram it) ''' + «generatedMemberComment('Extended request data key to hold editpart visual id.')» + public static final String VISUAL_ID_KEY = "visual_id"; «nonNLS()» + «generatedMemberComment('Extended request data key to hold the edge view during a reconnect request.')» + public static final String GRAPHICAL_RECONNECTED_EDGE = "graphical_edge"; «nonNLS» + «generatedMemberComment()» + private final org.eclipse.gmf.runtime.emf.type.core.IElementType myElementType; + ''' + + override semanticPart(GenDiagram it) ''' + «getSemanticCommand(it)» + + «addDeleteViewCommand(it)» + + «getEditHelperCommand(it)» + + «getContextElementType(it)» + + «getSemanticCommandSwitch(it)» + + «getConfigureCommand(it)» + + «getCreateRelationshipCommand(it)» + + «getCreateCommand(it)» + + «getCreateSemanticServiceEditCommand(it)» + + «getSetCommand(it)» + + «getEditContextCommand(it)» + + «getDestroyElementCommand(it)» + + «getDestroyReferenceCommand(it)» + + «getDuplicateCommand(it)» + + «getMoveCommand(it)» + + «getReorientReferenceRelationshipCommand(it)» + + «getReorientRelationshipCommand(it)» + + «getGEFWrapper(it)» + ''' + + override getContextElementType(GenDiagram it) ''' + «generatedMemberComment()» + protected org.eclipse.gmf.runtime.emf.type.core.IElementType getContextElementType(org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest request) { + org.eclipse.gmf.runtime.emf.type.core.IElementType requestContextElementType = «xptElementTypes.qualifiedClassName(it)».getElementType(getVisualID(request)); + return requestContextElementType != null ? requestContextElementType : myElementType; + } + ''' + + override getCreateRelationshipCommand(GenDiagram it) ''' +«generatedMemberComment()» +protected org.eclipse.gef.commands.Command getCreateRelationshipCommand(org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest req) { + «IF it.eResource.allContents.filter(typeof(GenerateUsingElementTypeCreationCommand)).size < 1» + return null; + «ENDIF» + «IF it.eResource.allContents.filter(typeof(GenerateUsingElementTypeCreationCommand)).size() > 0» + org.eclipse.papyrus.infra.services.edit.service.IElementEditService commandService = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(((org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart)getHost()).resolveSemanticElement()); + if(req.getElementType() != null) { + commandService = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(req.getElementType(), req.getClientContext()); + } + + if(commandService == null) { + return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE; + } + + org.eclipse.gmf.runtime.common.core.command.ICommand semanticCommand = commandService.getEditCommand(req); + + if((semanticCommand != null) && (semanticCommand.canExecute())) { + return getGEFWrapper(semanticCommand); + } + return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE; + «ENDIF» +} +''' + + override getCreateCommand(GenDiagram it) ''' +«generatedMemberComment()» + protected org.eclipse.gef.commands.Command getCreateCommand(org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest req) { + org.eclipse.gmf.runtime.emf.type.core.IElementType requestElementType = req.getElementType(); + if (requestElementType instanceof org.eclipse.gmf.runtime.emf.type.core.IElementType) { + org.eclipse.papyrus.infra.services.edit.service.IElementEditService commandProvider = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(req.getContainer()); + if (commandProvider != null) { + org.eclipse.gmf.runtime.common.core.command.ICommand command = commandProvider.getEditCommand(req); + if (command != null && command.canExecute()) { + return new org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy(command); + } + } + } + return null; + } +''' + + + override getMoveCommand(GenDiagram it) ''' +«generatedMemberComment()» +protected org.eclipse.gef.commands.Command getMoveCommand(org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest req) { + ««« BEGIN: PapyrusGenCode + ««« add move command + org.eclipse.emf.ecore.EObject targetCEObject = req.getTargetContainer(); + if(targetCEObject != null) { + org.eclipse.papyrus.infra.services.edit.service.IElementEditService provider = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(targetCEObject); + if(provider != null) { + org.eclipse.gmf.runtime.common.core.command.ICommand moveCommand = provider.getEditCommand(req); + if(moveCommand != null) { + return new org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy(moveCommand); + } + } + return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE; + } else { + return getGEFWrapper(new org.eclipse.gmf.runtime.emf.type.core.commands.MoveElementsCommand(req)); + } + ««« END: PapyrusGenCode + +} +''' + + /** + * FIXME need to check constraint's provider to ensure we don't generate a field + * for e.g. Java (or Literal, which is unlikely, though) expressions + * + * [Papyrus Quick Fix] Do not generate field when the expression is provided + * by a GenJavaExpressionProvider. + */ + override linkConstraints(GenDiagram it) ''' + + «generatedMemberComment()» + public static «getLinkCreationConstraintsClassName()» getLinkConstraints() { + «getLinkCreationConstraintsClassName()» cached = «xptPluginActivator.instanceAccess(it.editorGen)».getLinkConstraints(); + if (cached == null) { + «xptPluginActivator.instanceAccess(it.editorGen)».setLinkConstraints(cached = new «getLinkCreationConstraintsClassName()»()); + } + return cached; + } + +«generatedClassComment()» +public static class «getLinkCreationConstraintsClassName()» { + + «generatedMemberComment» + public «getLinkCreationConstraintsClassName()»() {«««package-local for the BaseItemSemanticEditPolicy to instantiate. Perhaps, protected is better (i.e. if someone subclasses it?) + // use static method #getLinkConstraints() to access instance + } + + «FOR nextLink : it.links» + «canCreate(nextLink)» + «ENDFOR» + + «FOR nextLink : it.links» + «canExist(nextLink)» + «ENDFOR» +} +''' + + /** + * [MG] extracted from LET statement, @see checkEMFConstraints(TypeLinkModelFacet) + */ + private def checkChildFeatureBounds(TypeLinkModelFacet it) { + childMetaFeature != containmentMetaFeature && !isUnbounded(childMetaFeature.ecoreFeature) + } + + def checkEMFConstraints(TypeLinkModelFacet it) ''' +«IF containmentMetaFeature.ecoreFeature != null» + «IF ! isUnbounded(containmentMetaFeature.ecoreFeature) || checkChildFeatureBounds(it)» + if («getContainerVariable(it)» != null) { + «checkEMFConstraints(containmentMetaFeature, it)» + «IF checkChildFeatureBounds(it)» + «checkEMFConstraints(childMetaFeature, it)» + «ENDIF» + } + «ENDIF» +«ENDIF» +''' + + override checkEMFConstraints(GenFeature it, TypeLinkModelFacet modelFacet) ''' +«IF modelFacet.containmentMetaFeature.ecoreFeature != null» +«IF ! isUnbounded(ecoreFeature)» +if («featureBoundComparator(it, getContainerVariable(modelFacet), modelFacet.getSourceType())») { + return false; +} +«ENDIF» +«ENDIF» +''' + + override canCreate(GenLink it) ''' +«generatedMemberComment()» +public boolean canCreate«stringUniqueIdentifier()»( +«IF !it.sansDomain» +«canCreateParameters(it.modelFacet)» +«ENDIF» +) { + «IF !it.sansDomain» + «checkEMFConstraints(it.modelFacet)» + «ENDIF» + return canExist«stringUniqueIdentifier()»( + «IF !it.sansDomain» + «canCreateValues(it.modelFacet)» + «ENDIF» + ); +} +''' + + override featureBoundsConditionClause(GenFeature it, String targetVar, GenClass targetType) ''' +«««Checking upper bounds if was specified in MM +«IF ecoreFeature != null» + «IF ! isUnbounded(ecoreFeature)»«featureBoundComparator(it, targetVar, targetType)»«ENDIF» + ««« Checking uniqueness in addition if upper bounds != 1 + «IF ! isSingleValued(ecoreFeature) && ! isUnbounded(ecoreFeature)» || «ENDIF» + ««« Checking uniqueness in if upper bounds !- 1 + «IF ! isSingleValued(ecoreFeature)»«featureUniquenessComparator(it, targetVar, targetType)»«ENDIF» +«ENDIF» +''' + + override featureBoundComparator(GenFeature it, String featureVar, GenClass featureVarGenClass) ''' + «xptMetaModel.getFeatureValue(it, featureVar, featureVarGenClass)» + «IF ecoreFeature.upperBound == 1» + != null + «ELSE» + .size() >= «ecoreFeature.upperBound» + «ENDIF» + ''' + + // Generate generic method if using semantic creation command based on element types framework. + def getCreateSemanticServiceEditCommand(GenDiagram it) ''' +«IF it.eResource.allContents.filter(typeof(GenerateUsingElementTypeCreationCommand)).size > 0» + «generatedMemberComment» + protected org.eclipse.gmf.runtime.common.core.command.ICommand getSemanticCreationCommand(org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest req) { + org.eclipse.papyrus.infra.services.edit.service.IElementEditService commandService = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(req.getContainer()); + if(commandService == null) { + return org.eclipse.gmf.runtime.common.core.command.UnexecutableCommand.INSTANCE; + } + return commandService.getEditCommand(req); + } +«ENDIF» +''' + + /** + * XXX for now, both constraints are injected into single method + * which may not be suitable for modification especially when mixing + * java and ocl constraints (former requires manual code). + * Better approach would be: + * if either is non-null and providers are not the same - introduce two methods, + * to check source and target separately. Otherwize, do it inplace. +*/ + override canExist(GenLink it) ''' + «generatedMemberComment()» + public boolean canExist«stringUniqueIdentifier()»( + «IF !it.sansDomain» + «canExistParameters(it.modelFacet)» + «ENDIF» + ) { + «IF creationConstraints != null && creationConstraints.isValid() && it.diagram.editorGen.expressionProviders != null» + try { + «IF creationConstraints.sourceEnd != null» + «checkAdditionalConstraint(creationConstraints.sourceEnd.provider, creationConstraints.sourceEnd, 'source', 'target', creationConstraints.getSourceEndContextClass(), creationConstraints.getTargetEndContextClass())» + «ENDIF» + «IF creationConstraints.targetEnd != null» + «checkAdditionalConstraint(creationConstraints.targetEnd.provider, creationConstraints.targetEnd, 'target', 'source', creationConstraints.getTargetEndContextClass(), creationConstraints.getSourceEndContextClass())» + «ENDIF» + return true; + } catch(Exception e) { + «xptPluginActivator.instanceAccess(it.diagram.editorGen)».logError("Link constraint evaluation error", e); «nonNLS()» + return false; + } + «ELSE» + return true; + «ENDIF» + } + ''' + + override def getGEFWrapper(GenDiagram it) ''' + «generatedMemberComment()» + protected final org.eclipse.gef.commands.Command getGEFWrapper(org.eclipse.gmf.runtime.common.core.command.ICommand cmd) { + return (cmd == null) ? org.eclipse.gef.commands.UnexecutableCommand.INSTANCE : new org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy(cmd); + } + ''' + +} |