Skip to main content
summaryrefslogblamecommitdiffstats
blob: e907969828acff01a2e18c962b6cd73472234ec5 (plain) (tree)

























































































                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     














                                                                                                                                                                  





















































































































































































































































































































                                                                                                                                                                                                                                                                                               
/**
 * Copyright (c) 2007, 2010 Borland Software Corporation 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
 */
package aspects.xpt.diagram.editpolicies

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.Common
import xpt.OclMigrationProblems_qvto
import xpt.diagram.editpolicies.Utils_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 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) {
				Integer id = new Integer(«getVisualIDMethodCall(it)»((org.eclipse.gmf.runtime.notation.View) view));
				request.getExtendedData().put(VISUAL_ID_KEY, id);
				request.getExtendedData().put(GRAPHICAL_RECONNECTED_EDGE, (org.eclipse.gmf.runtime.notation.View)view);
			}
		}
		return super.getCommand(request);
	}
	
	«generatedMemberComment('Returns visual id from request parameters.')»
	protected int getVisualID(org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest request) {
		Object id = request.getParameter(VISUAL_ID_KEY);
		return id instanceof Integer ? ((Integer) id).intValue() : -1;
	}

	«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)»
		
		// RS: add code for extended types
		«getCreateExtendedTypeCommand(it)»
		«getExtendedStartCreateRelationshipCommand(it)»
		«getExtendedCompleteCreateRelationshipCommand(it)»
		// RS: End of add code for extended types
		«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());
	}

	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) {
 		// no more usage of the extended types here. 
        return null;
  }
'''

	def getCreateExtendedTypeCommand(GenDiagram it) '''
«generatedMemberComment»
 protected org.eclipse.gef.commands.Command getExtendedTypeCreationCommand(org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest request, org.eclipse.papyrus.infra.extendedtypes.types.IExtendedHintedElementType requestElementType) {
		org.eclipse.papyrus.infra.services.edit.service.IElementEditService provider = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(request.getContainer());
		if(provider == null) {
			return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE;
		}
		// Retrieve create command from the Element Edit service
		org.eclipse.gmf.runtime.common.core.command.ICommand createGMFCommand = provider.getEditCommand(request);
		return getGEFWrapper(createGMFCommand);
	}
'''

	def getExtendedStartCreateRelationshipCommand(GenDiagram it) '''
«generatedMemberComment»
 protected org.eclipse.gef.commands.Command getExtendedStartCreateRelationshipCommand(org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest request, org.eclipse.papyrus.infra.extendedtypes.types.IExtendedHintedElementType requestElementType) {
	org.eclipse.papyrus.infra.services.edit.service.IElementEditService provider = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(requestElementType);
	if(provider == null) {
		return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE;
	}
	// Retrieve create command from the Element Edit service
	org.eclipse.gmf.runtime.common.core.command.ICommand createGMFCommand = provider.getEditCommand(request);
	return getGEFWrapper(createGMFCommand);
}
'''

	def getExtendedCompleteCreateRelationshipCommand(GenDiagram it) '''
«generatedMemberComment»
 protected org.eclipse.gef.commands.Command getExtendedCompleteCreateRelationshipCommand(org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest request, org.eclipse.papyrus.infra.extendedtypes.types.IExtendedHintedElementType requestElementType) {
	org.eclipse.papyrus.infra.services.edit.service.IElementEditService provider = org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils.getCommandProvider(requestElementType);
	if(provider == null) {
		return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE;
	}
	// Retrieve create command from the Element Edit service
	org.eclipse.gmf.runtime.common.core.command.ICommand createGMFCommand = provider.getEditCommand(request);
	return getGEFWrapper(createGMFCommand);
}
'''

	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«getUniqueIdentifier()»(
«IF !it.sansDomain»
«canCreateParameters(it.modelFacet)»
«ENDIF»
) {
	«IF !it.sansDomain»
	«checkEMFConstraints(it.modelFacet)»
	«ENDIF»
	return canExist«getUniqueIdentifier()»(
	«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«getUniqueIdentifier()»(
		«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»
		}
	'''

}

Back to the top