blob: 3e1c760e85b7e1d27a54de778e43351757037a87 [file] [log] [blame]
/**
* Copyright (c) 2007, 2010, 2013 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 (Borland) - [243151] explicit source/target for links
* Michael Golubev (Montages) - API extracted to gmf.tooling.runtime, template migrated to Xtend2
*/
package xpt.diagram.updater
import com.google.inject.Inject
import metamodel.MetaModel
import org.eclipse.gmf.codegen.gmfgen.FeatureLinkModelFacet
import org.eclipse.gmf.codegen.gmfgen.GenCommonBase
import org.eclipse.gmf.codegen.gmfgen.GenCompartment
import org.eclipse.gmf.codegen.gmfgen.GenContainerBase
import org.eclipse.gmf.codegen.gmfgen.GenDiagramUpdater
import org.eclipse.gmf.codegen.gmfgen.GenLink
import org.eclipse.gmf.codegen.gmfgen.GenLinkEnd
import org.eclipse.gmf.codegen.gmfgen.GenNode
import org.eclipse.gmf.codegen.gmfgen.LinkModelFacet
import org.eclipse.gmf.codegen.gmfgen.TypeLinkModelFacet
import org.eclipse.gmf.codegen.xtend.annotations.MetaDef
import xpt.CodeStyle
import xpt.Common
import xpt.Common_qvto
import xpt.GenModelUtils_qvto
import xpt.editor.VisualIDRegistry
import xpt.providers.ElementTypes
@com.google.inject.Singleton class DiagramUpdater {
@Inject extension Common;
@Inject extension Common_qvto;
@Inject extension Utils_qvto;
@Inject extension GenModelUtils_qvto;
@Inject VisualIDRegistry xptVisualIDRegistry;
@Inject MetaModel xptMetaModel;
@Inject ElementTypes xptElementTypes;
@Inject CodeStyle xptCodeStyle;
@Inject NodeDescriptor nodeDescriptor;
@Inject LinkDescriptor linkDescriptor;
@MetaDef def getSemanticChildrenMethodName(GenContainerBase it) '''get«getUniqueIdentifier()»SemanticChildren'''
@MetaDef def getSemanticChildrenMethodCall(GenContainerBase it) '''«qualifiedClassName(getDiagram().editorGen.diagramUpdater)».«getSemanticChildrenMethodName(it)»'''
@MetaDef def getContainedLinksMethodCall(GenCommonBase it) '''«doGetSomeLinksMethodCall(it, UpdaterLinkType::CONTAINED)»'''
@MetaDef def getIncomingLinksMethodCall(GenCommonBase it) '''«doGetSomeLinksMethodCall(it, UpdaterLinkType::INCOMING)»'''
@MetaDef def getOutgoingLinksMethodCall(GenCommonBase it) '''«doGetSomeLinksMethodCall(it, UpdaterLinkType::OUTGOING)»'''
@MetaDef protected def doGetSomeLinksMethodCall(GenCommonBase it, UpdaterLinkType linkType) '''«qualifiedClassName(it.getDiagram().diagramUpdater)».«linkGetterName(linkType)»'''
@MetaDef protected def linkGetterName(GenCommonBase it, UpdaterLinkType linkType) '''get«it.uniqueIdentifier»«linkType.linkMethodSuffix»Links'''
@MetaDef def runtimeTypedInstanceName(GenDiagramUpdater it) '''TYPED_INSTANCE'''
@MetaDef def runtimeTypedInstanceCall(GenDiagramUpdater it) '''«qualifiedClassName(it)».«runtimeTypedInstanceName(it)»'''
def className(GenDiagramUpdater it) '''«diagramUpdaterClassName»'''
def packageName(GenDiagramUpdater it) '''«it.editorGen.editor.packageName»'''
def qualifiedClassName(GenDiagramUpdater it) '''«packageName(it)».«className(it)»'''
def fullPath(GenDiagramUpdater it) '''«qualifiedClassName(it)»'''
def DiagramUpdater(GenDiagramUpdater it) '''
«copyright(editorGen)»
package «packageName(it)»;
«generatedClassComment»
public class «className(it)» {
«isShortcutOrphaned(it)»
«var semanticContainers = it.editorGen.diagram.allContainers.filter[container | hasSemanticChildren(container)]»
«getGenericSemanticChildrenOfView(it, semanticContainers)»
«FOR next : semanticContainers»
«getSemanticChildrenOfView(next)»
«ENDFOR»
«getPhantomNodesIterator(it)»
«getGenericConnectedLinks(it, getAllSemanticElements(editorGen.diagram), UpdaterLinkType::CONTAINED)»
«getGenericConnectedLinks(it, getAllSemanticDiagramElements(editorGen.diagram), UpdaterLinkType::INCOMING)»
«getGenericConnectedLinks(it, getAllSemanticDiagramElements(editorGen.diagram), UpdaterLinkType::OUTGOING)»
«FOR e : getAllSemanticElements(editorGen.diagram)»
«getContainedLinks(e)»
«ENDFOR»
«FOR e : getAllSemanticDiagramElements(editorGen.diagram)»
«getIncomingLinks(e)»
«ENDFOR»
«FOR e : getAllSemanticDiagramElements(editorGen.diagram)»
«getOutgoingLinks(e)»
«ENDFOR»
«FOR link : getAllContainedLinks(editorGen.diagram)»
«getContainedLinksByTypeMethod(link)»
«ENDFOR»
«FOR link : getAllIncomingLinks(editorGen.diagram)»
«getIncomingLinksByTypeMethod(link)»
«ENDFOR»
«FOR link : getAllOutgoingLinks(editorGen.diagram)»
«getOutgoingLinksByTypeMethod(link)»
«ENDFOR»
«runtimeTypedInstance(it)»
«additions(it)»
}
'''
/**
* Currently shortcuts are supported only for domain-based diagram element.
* This means, view.isSetElement() == true.
*/
def isShortcutOrphaned(GenDiagramUpdater it) '''
«IF editorGen.diagram.containsShortcutsTo.notEmpty»
«generatedMemberComment»
public static boolean isShortcutOrphaned(org.eclipse.gmf.runtime.notation.View view) {
return !view.isSetElement() || view.getElement() == null || view.getElement().eIsProxy();
}
«ENDIF»
'''
protected def GenDiagramUpdater diagramUpdater(GenCommonBase base) {
return base.diagram.editorGen.diagramUpdater
}
protected def nodeDescriptorQualifiedClassName(GenCommonBase it) '''«nodeDescriptor.qualifiedClassName(it.diagramUpdater)»'''
protected def linkDescriptorQualifiedClassName(GenCommonBase it) '''«linkDescriptor.qualifiedClassName(it.diagramUpdater)»'''
protected def dispatch CharSequence listOfNodeDescriptors(GenDiagramUpdater it) '''java.util.List<«nodeDescriptor.qualifiedClassName(it)»>'''
protected def dispatch CharSequence listOfNodeDescriptors(GenCommonBase it) '''«listOfNodeDescriptors(it.diagramUpdater)»'''
protected def dispatch CharSequence listOfLinkDescriptors(GenDiagramUpdater it) '''java.util.List<«linkDescriptor.qualifiedClassName(it)»>'''
protected def dispatch CharSequence listOfLinkDescriptors(GenCommonBase it) '''«listOfLinkDescriptors(it.diagramUpdater)»'''
protected def CharSequence newEmptyList() '''java.util.Collections.emptyList()'''
protected def CharSequence newLinkedListOfNodeDescriptors(GenDiagramUpdater it, String varName) '''java.util.LinkedList<«nodeDescriptor.qualifiedClassName(it)»> result = new java.util.LinkedList<«it.nodeDescriptorQualifiedClassName»>'''
protected def CharSequence newLinkedListOfLinkDescriptors(GenDiagramUpdater it, String varName) '''java.util.LinkedList<«linkDescriptor.qualifiedClassName(it)»> result = new java.util.LinkedList<«it.linkDescriptorQualifiedClassName»>'''
protected def typeOfCrossReferenceMap() '''java.util.Map<org.eclipse.emf.ecore.EObject, java.util.Collection<org.eclipse.emf.ecore.EStructuralFeature.Setting>>'''
def getGenericSemanticChildrenOfView(GenDiagramUpdater it, Iterable<GenContainerBase> semanticContainers) '''
«generatedMemberComment»
public static «listOfNodeDescriptors» getSemanticChildren(org.eclipse.gmf.runtime.notation.View view) {
«IF semanticContainers.notEmpty»
switch («xptVisualIDRegistry.getVisualIDMethodCall(editorGen.diagram)»(view)) {
«FOR next : semanticContainers»
«getSemanticChildrenCase(next)»
«ENDFOR»
}
«ENDIF»
return «newEmptyList()»;
}
'''
def getSemanticChildrenCase(GenContainerBase it) '''
«xptVisualIDRegistry.caseVisualID(it)»
return «getSemanticChildrenMethodName(it)»(view);
'''
def getSemanticChildrenOfView(GenContainerBase it) '''
«generatedMemberComment»
public static «listOfNodeDescriptors» «getSemanticChildrenMethodName(it)»(org.eclipse.gmf.runtime.notation.View view) {
«IF getSemanticChildrenChildFeatures(it).notEmpty || it.getPhantomNodes().notEmpty»
«defineModelElement(it)»
«newLinkedListOfNodeDescriptors(it.diagramUpdater, 'result')»();
«/* childMetaFeature can be null here! */
FOR childMetaFeature : getSemanticChildrenChildFeatures(it)»
«IF null == childMetaFeature»
{ /*FIXME no containment/child feature found in the genmodel, toolsmith need to specify Class here manually*/ childElement =
/*FIXME no containment/child feature found in the genmodel, toolsmith need to specify correct one here manually*/;
«ELSEIF childMetaFeature.listType»
for (java.util.Iterator<?> it = «xptMetaModel.getFeatureValue(childMetaFeature, 'modelElement', it.getModelElementType())».iterator(); it.hasNext();) {
«xptMetaModel.DeclareAndAssign(childMetaFeature.typeGenClass, 'childElement', 'it.next()', true)»
«ELSE»
{ «xptMetaModel.DeclareAndAssign(childMetaFeature.typeGenClass, 'childElement', 'modelElement', it.getModelElementType(), childMetaFeature)»
«ENDIF»
int visualID = «xptVisualIDRegistry.getNodeVisualIDMethodCall(it.diagram)»(view, «xptMetaModel.DowncastToEObject(childMetaFeature.typeGenClass, 'childElement')»);
«FOR next : getSemanticChildren(it, childMetaFeature)»
«checkChildElementVisualID(next, null != childMetaFeature && childMetaFeature.listType)»
«ENDFOR»
}
«ENDFOR»
«IF it.getPhantomNodes.notEmpty»
org.eclipse.emf.ecore.resource.Resource resource = modelElement.eResource();
for (java.util.Iterator<org.eclipse.emf.ecore.EObject> it = getPhantomNodesIterator(resource); it.hasNext();) {
org.eclipse.emf.ecore.EObject childElement = it.next();
if (childElement == modelElement) {
continue;
}
«FOR phantom : it.phantomNodes»
«addNextIfPhantom(phantom)»
«ENDFOR»
}
«ENDIF»
return result;
«ELSE»
return «newEmptyList()»;
«ENDIF»
}
'''
def dispatch defineModelElement(GenContainerBase it) '''
if (!view.isSetElement()) {
return «newEmptyList()»;
}
«xptMetaModel.DeclareAndAssign(it.getModelElementType(), 'modelElement', 'view.getElement()')»
'''
def dispatch defineModelElement(GenCompartment it) '''
if (false == view.eContainer() instanceof org.eclipse.gmf.runtime.notation.View) {
return «newEmptyList()»;
}
org.eclipse.gmf.runtime.notation.View containerView = (org.eclipse.gmf.runtime.notation.View) view.eContainer();
if (!containerView.isSetElement()) {
return «newEmptyList()»;
}
«xptMetaModel.DeclareAndAssign(it.getModelElementType(), 'modelElement', 'containerView.getElement()')»
'''
/**
* XXX: [MG] suspicious code inside, EVEN after I moved ", " into the IF, there still may be problem if inner IF condition is not met.
* Need to check with case when it.modelFacet.childMetaFeature == null
*/
def checkChildElementVisualID(GenNode it, Boolean inLoop) '''
if (visualID == «VisualIDRegistry::visualID(it)») {
result.add(new «nodeDescriptor.qualifiedClassName(it.getDiagram().diagramUpdater)»(«IF null != modelFacet.childMetaFeature»«xptMetaModel.DowncastToEObject(modelFacet.childMetaFeature.typeGenClass, 'childElement')», «ENDIF»visualID));
«IF inLoop»
continue;
«ENDIF»
}
'''
def addNextIfPhantom(GenNode it) '''
if («xptVisualIDRegistry.getNodeVisualIDMethodCall(it.diagram)»(view, childElement) == «VisualIDRegistry::visualID(it)») {
result.add(new «nodeDescriptor.qualifiedClassName(it.getDiagram().diagramUpdater)»(childElement, «VisualIDRegistry::visualID(it)»));
continue;
}
'''
def getPhantomNodesIterator(GenDiagramUpdater it) '''
«IF editorGen.diagram.hasPhantomNodes»
«generatedMemberComment»
private static java.util.Iterator<org.eclipse.emf.ecore.EObject> getPhantomNodesIterator(org.eclipse.emf.ecore.resource.Resource resource) {
return resource.getAllContents();
}
«ENDIF»
'''
def getGenericConnectedLinks(GenDiagramUpdater it, Iterable<? extends GenCommonBase> linkContainers, UpdaterLinkType linkType) '''
«generatedMemberComment»
public static «listOfLinkDescriptors» get«linkType.linkMethodSuffix»Links(org.eclipse.gmf.runtime.notation.View view) {
«IF linkContainers.notEmpty»
switch («xptVisualIDRegistry.getVisualIDMethodCall(it.editorGen.diagram)»(view)) {
«FOR next : linkContainers»
«getContainedLinksCase(next, linkType)»
«ENDFOR»
}
«ENDIF»
return «newEmptyList»;
}
'''
def getContainedLinksCase(GenCommonBase it, UpdaterLinkType linkType) '''
«xptVisualIDRegistry.caseVisualID(it)»
return «linkGetterName(linkType)»(view);
'''
def dispatch getContainedLinks(GenCommonBase it) '''
«getConnectedLinks(it, computeContainedLinks(it.metaClass, diagram), UpdaterLinkType::CONTAINED, false)»
'''
def dispatch getContainedLinks(GenLink it) '''
«getConnectedLinks(it, computeContainedLinks(it.metaClass, diagram), UpdaterLinkType::CONTAINED, false)»
'''
def getIncomingLinks(GenLinkEnd it) '''
«getConnectedLinks(it, computeIncomingLinks(it), UpdaterLinkType::INCOMING, true)»
'''
def getOutgoingLinks(GenLinkEnd it) '''
«getConnectedLinks(it, computeOutgoingLinks(it), UpdaterLinkType::OUTGOING, false)»
'''
def getConnectedLinks(GenCommonBase it, Iterable<GenLink> genLinks, UpdaterLinkType linkType, boolean needCrossReferencer) '''
«generatedMemberComment»
public static «listOfLinkDescriptors(it)» «linkGetterName(it, linkType)»(org.eclipse.gmf.runtime.notation.View view) {
«IF genLinks.notEmpty»
«xptMetaModel.DeclareAndAssign(it.metaClass, 'modelElement', 'view.getElement()')»
«IF needCrossReferencer»
«typeOfCrossReferenceMap» crossReferences = org.eclipse.emf.ecore.util.EcoreUtil.CrossReferencer.find(view.eResource().getResourceSet().getResources());
«ENDIF»
«newLinkedListOfLinkDescriptors(it.diagramUpdater, 'result')»();
«FOR link : genLinks»
«colectConnectedLinks(link, linkType, needCrossReferencer, isExternalInterface(it.metaClass))»
«ENDFOR»
return result;
«ELSE»
return «newEmptyList()»;
«ENDIF»
}
'''
def colectConnectedLinks(GenLink it, UpdaterLinkType linkType, boolean needCrossReferencer, boolean isExternalInterface) '''
«IF it.modelFacet != null»
«IF isExternalInterface && !it.modelFacet.oclIsKindOf(typeof(FeatureLinkModelFacet))»
if («xptMetaModel.IsInstance(it.modelFacet.getLinkEndType(linkType), 'modelElement')») {
«ENDIF»
result.addAll(«chooseConnectedLinksByTypeMethodName(it.modelFacet, linkType, it)»(« //
IF isExternalInterface && !it.modelFacet.oclIsKindOf(typeof(FeatureLinkModelFacet))»«xptMetaModel.CastEObject(it.modelFacet.getLinkEndType(linkType), 'modelElement')»«ELSE»modelElement«ENDIF»«IF needCrossReferencer», crossReferences«ENDIF»));
«IF isExternalInterface && !it.modelFacet.oclIsKindOf(typeof(FeatureLinkModelFacet))»
}
«ENDIF»
«ENDIF»
'''
def dispatch chooseConnectedLinksByTypeMethodName(LinkModelFacet it, UpdaterLinkType type, GenLink genLink) '''«incorrectLinkModelFacet(it)»'''
/**
* For FeatureModelFacet-based links we are calling getOutgoing???Links instead of getContained???Links
*/
def dispatch chooseConnectedLinksByTypeMethodName(FeatureLinkModelFacet it, UpdaterLinkType type, GenLink genLink) '''
«IF type == UpdaterLinkType::CONTAINED»
«getConnectedLinksByTypeMethodName(genLink, UpdaterLinkType::OUTGOING)»
«ELSE»
«getConnectedLinksByTypeMethodName(genLink, type)»
«ENDIF»
'''
/**
* For TypeModelFacet-based links without specified sourceMetaFeature, we are calling getContained???Links instead of getOutgoinf???Links
*/
def dispatch chooseConnectedLinksByTypeMethodName(TypeLinkModelFacet it, UpdaterLinkType type, GenLink genLink) '''
«IF type == UpdaterLinkType::OUTGOING && sourceMetaFeature == null»
«getConnectedLinksByTypeMethodName(genLink, UpdaterLinkType::CONTAINED)»
«ELSE»
«getConnectedLinksByTypeMethodName(genLink, type)»
«ENDIF»
'''
def getContainedLinksByTypeMethod(GenLink it) '''«getContainedLinksByTypeMethod(it.modelFacet, it)»'''
def getConnectedLinksByTypeMethodName(GenLink it, UpdaterLinkType linkType) '''get«linkType.linkMethodSuffix»«getConnectedLinksByTypeMethodFragment(modelFacet)»_«visualID»'''
def dispatch getConnectedLinksByTypeMethodFragment(TypeLinkModelFacet it) '''TypeModelFacetLinks_«metaClass.ecoreClass.name»'''
def dispatch getConnectedLinksByTypeMethodFragment(FeatureLinkModelFacet it) '''FeatureModelFacetLinks_«metaFeature.genClass.ecoreClass.name»_«metaFeature.ecoreFeature.name.toFirstUpper()»'''
def dispatch getConnectedLinksByTypeMethodFragment(LinkModelFacet it) '''«incorrectLinkModelFacet(it)»'''
def dispatch getContainedLinksByTypeMethod(LinkModelFacet it, GenLink genLink) '''«incorrectLinkModelFacet(it)»'''
def dispatch getContainedLinksByTypeMethod(FeatureLinkModelFacet it, GenLink genLink) ''''''
def dispatch getContainedLinksByTypeMethod(TypeLinkModelFacet it, GenLink genLink) '''
«generatedMemberComment»
private static java.util.Collection<«linkDescriptor.qualifiedClassName(genLink.diagramUpdater)»> «getConnectedLinksByTypeMethodName(genLink, UpdaterLinkType::CONTAINED)»(«xptMetaModel.QualifiedClassName(childMetaFeature.genClass)» container) {
«getContainedLinksByTypeMethodBody(it, genLink, false)»
}
'''
def getContainedLinksByTypeMethodBody(TypeLinkModelFacet it, GenLink genLink, boolean sourceVarDefined) '''
«newLinkedListOfLinkDescriptors(genLink.diagramUpdater, 'result')»();
«var inLoop = childMetaFeature.listType»
«IF inLoop»
for (java.util.Iterator<?> links = «xptMetaModel.getFeatureValue(childMetaFeature, 'container', childMetaFeature.genClass)».iterator(); links.hasNext();) {
org.eclipse.emf.ecore.EObject linkObject = (org.eclipse.emf.ecore.EObject ) links.next();
if («xptMetaModel.NotInstance(metaClass, 'linkObject')») {
continue;
}
«xptMetaModel.DeclareAndAssign(metaClass, 'link', 'linkObject')»
«ELSE»
«IF childMetaFeature.typeGenClass == metaClass»
«xptMetaModel.DeclareAndAssign(metaClass, 'link', 'container', it.sourceType, childMetaFeature)»
«ELSE»
«xptMetaModel.DeclareAndAssign(childMetaFeature.typeGenClass, 'linkObject', 'container', it.sourceType, childMetaFeature)»
if («xptMetaModel.NotInstance(metaClass, 'linkObject')») {
return result;
}
«xptMetaModel.DeclareAndAssign(metaClass, 'link', 'linkObject')»
«ENDIF»
«ENDIF»
«checkLinkVisualID(it, genLink, inLoop)»
«defineLinkDestination(it, inLoop)»
«IF null != sourceMetaFeature»
«defineLinkSource(it, inLoop)»
«IF sourceVarDefined»
«checkLinkSource(it, inLoop)»
«ENDIF»
«addLinkDescriptor(it, genLink, 'src', 'dst')»
«ELSE»
«addLinkDescriptor(it, genLink, 'container', 'dst')»
«ENDIF»
«IF inLoop»
}
«ENDIF»
return result;
'''
def addLinkDescriptor(TypeLinkModelFacet it, GenLink genLink, String srcVar, String dstVar) '''
result.add(new «linkDescriptor.qualifiedClassName(genLink.diagramUpdater)»(«//
xptMetaModel.DowncastToEObject(it.sourceType, srcVar)», «//
xptMetaModel.DowncastToEObject(it.targetType, dstVar)», «//
xptMetaModel.DowncastToEObject(metaClass, 'link')», «//
xptElementTypes.accessElementType(genLink)», «VisualIDRegistry::visualID(genLink)»));
'''
def checkLinkVisualID(TypeLinkModelFacet it, GenLink genLink, boolean inLoop) '''
if («VisualIDRegistry::visualID(genLink)» != «xptVisualIDRegistry.getLinkWithClassVisualIDMethodCall(genLink.diagram)»(«xptMetaModel.DowncastToEObject(metaClass, 'link')»)) {
«stopLinkProcessing(inLoop)»
}
'''
def defineLinkSource(TypeLinkModelFacet it, boolean inLoop) '''
«IF sourceMetaFeature.listType»
java.util.List sources = «xptMetaModel.getFeatureValue(sourceMetaFeature, 'link', metaClass)»;
Object theSource = sources.size() == 1 ? sources.get(0) : null;
if («xptMetaModel.NotInstance(it.sourceType, 'theSource')») {
«stopLinkProcessing(inLoop)»
}
«xptMetaModel.DeclareAndAssign(it.sourceType, 'src', 'theSource', true)»
«ELSE»
«xptMetaModel.DeclareAndAssign(it.sourceType, 'src', 'link', metaClass, sourceMetaFeature)»
«ENDIF»
'''
def checkLinkSource(TypeLinkModelFacet it, boolean inLoop) '''
if (src != source) {
«stopLinkProcessing(inLoop)»
}
'''
def defineLinkDestination(TypeLinkModelFacet it, Boolean inLoop) '''
«IF targetMetaFeature.listType»
java.util.List targets = «xptMetaModel.getFeatureValue(it.targetMetaFeature, 'link', metaClass)»;
Object theTarget = targets.size() == 1 ? targets.get(0) : null;
if («xptMetaModel.NotInstance(it.targetType, 'theTarget')») {
«stopLinkProcessing(inLoop)»
}
«xptMetaModel.DeclareAndAssign(it.targetType, 'dst', 'theTarget', true)»
«ELSE»
«xptMetaModel.DeclareAndAssign(it.targetType, 'dst', 'link', metaClass, targetMetaFeature)»
«ENDIF»
'''
def stopLinkProcessing(boolean inLoop) '''
«IF inLoop»
continue;
«ELSE»
return result;
«ENDIF»
'''
def getIncomingLinksByTypeMethod(GenLink it) '''
«generatedMemberComment»
private static java.util.Collection<«linkDescriptor.qualifiedClassName(it.diagramUpdater)»> «getConnectedLinksByTypeMethodName(UpdaterLinkType::INCOMING)»(«xptMetaModel.QualifiedClassName(it.modelFacet.targetType)» target, «typeOfCrossReferenceMap» crossReferences) {
«newLinkedListOfLinkDescriptors(it.diagramUpdater, 'result')»();
java.util.Collection<org.eclipse.emf.ecore.EStructuralFeature.Setting> settings = crossReferences.get(target);
for (org.eclipse.emf.ecore.EStructuralFeature.Setting setting : settings) {
«getIncomingLinksByTypeMethodBody(it.modelFacet, it)»
}
return result;
}
'''
def dispatch getIncomingLinksByTypeMethodBody(TypeLinkModelFacet it, GenLink genLink) '''
if (setting.getEStructuralFeature() != «xptMetaModel.MetaFeature(targetMetaFeature)» || «xptMetaModel.NotInstance(metaClass, 'setting.getEObject()')») {
continue;
}
«xptMetaModel.DeclareAndAssign(metaClass, 'link', 'setting.getEObject()')»
«checkLinkVisualID(it, genLink, true)»
«IF null != sourceMetaFeature»
«defineLinkSource(it, true)»
«addLinkDescriptor(it, genLink, 'src', 'target')»
«ELSE»
«defineLinkContainer(it, true)»
«addLinkDescriptor(it, genLink, 'container', 'target')»
«extraLineBreak»
«/*TODO: continue here.*/ //
ENDIF»
'''
def defineLinkContainer(TypeLinkModelFacet it, boolean inLoop) '''
if (false == «xptMetaModel.IsContainerInstance(containmentMetaFeature.genClass, 'link', metaClass)») {
«stopLinkProcessing(inLoop)»
}
«xptMetaModel.DeclareAndAssignContainer(containmentMetaFeature.genClass, 'container', 'link', metaClass)»
'''
def dispatch getIncomingLinksByTypeMethodBody(FeatureLinkModelFacet it, GenLink genLink) '''
if (setting.getEStructuralFeature() == «xptMetaModel.MetaFeature(it.metaFeature)») {
result.add(new «linkDescriptor.qualifiedClassName(genLink.diagramUpdater)»(setting.getEObject(), « //
xptMetaModel.DowncastToEObject(it.targetType, 'target')», « //
xptElementTypes.accessElementType(genLink)», « //
VisualIDRegistry::visualID(genLink)»));
}
'''
def dispatch getIncomingLinksByTypeMethodBody(LinkModelFacet it, GenLink genLink) '''«incorrectLinkModelFacet(it)»'''
def getOutgoingLinksByTypeMethod(GenLink it) '''
«getOutgoingLinksByTypeMethod(it.modelFacet, it)»
'''
def getOutgoingLinksByTypeMethodSignature(GenLink it) //
'''private static java.util.Collection<«linkDescriptor.qualifiedClassName(it.diagramUpdater)»> «getConnectedLinksByTypeMethodName(UpdaterLinkType::OUTGOING)»(«xptMetaModel.QualifiedClassName(it.modelFacet.sourceType)» source)'''
def dispatch getOutgoingLinksByTypeMethod(FeatureLinkModelFacet it, GenLink genLink) '''
«generatedMemberComment»
«getOutgoingLinksByTypeMethodSignature(genLink)» {
«newLinkedListOfLinkDescriptors(genLink.diagramUpdater, 'result')»();
«IF it.metaFeature.listType»
for (java.util.Iterator<?> destinations = «xptMetaModel.getFeatureValue(it.metaFeature, 'source', it.sourceType)».iterator(); destinations.hasNext();) {
«xptMetaModel.DeclareAndAssign(it.targetType, 'destination', 'destinations.next()', true)»
«ELSE»
«xptMetaModel.DeclareAndAssign(it.targetType, 'destination', 'source', sourceType, metaFeature)»
if (destination == null) {
return result;
}
«ENDIF»
result.add(new «linkDescriptor.qualifiedClassName(genLink.diagramUpdater)»(«xptMetaModel.DowncastToEObject(sourceType, 'source')», «xptMetaModel.DowncastToEObject(targetType, 'destination')», «xptElementTypes.accessElementType(genLink)», «VisualIDRegistry::visualID(genLink)»));
«IF metaFeature.listType»
}
«ENDIF»
return result;
}
'''
/**
* More careful way to find container should be used here then GMF will be modified in accordance
*/
def dispatch getOutgoingLinksByTypeMethod(TypeLinkModelFacet it, GenLink genLink) '''
«IF null != sourceMetaFeature»
«generatedMemberComment»
«getOutgoingLinksByTypeMethodSignature(genLink)» {
«xptMetaModel.QualifiedClassName(containmentMetaFeature.genClass)» container = null;
// Find container element for the link.
// Climb up by containment hierarchy starting from the source
// and return the first element that is instance of the container class.
for (org.eclipse.emf.ecore.EObject element = «xptMetaModel.DowncastToEObject(sourceType, 'source')»; element != null && container == null; element = element.eContainer()) {
if («xptMetaModel.IsInstance(containmentMetaFeature.genClass, 'element')») {
container = «xptMetaModel.CastEObject(containmentMetaFeature.genClass, 'element')»;
}
}
if (container == null) {
return «newEmptyList()»;
}
«getContainedLinksByTypeMethodBody(it, genLink, true)»
}
«ENDIF»
'''
def dispatch getOutgoingLinksByTypeMethod(LinkModelFacet it, GenLink genLink) '''«incorrectLinkModelFacet(it)»'''
def incorrectLinkModelFacet(LinkModelFacet it) '''«ERROR('Incorrect LinkModelFacet: ' + it)»'''
def runtimeTypedInstance(GenDiagramUpdater it) '''
«generatedMemberComment»
public static final org.eclipse.gmf.tooling.runtime.update.DiagramUpdater «runtimeTypedInstanceName(it)» = new org.eclipse.gmf.tooling.runtime.update.DiagramUpdater() {
«generatedMemberComment»
«xptCodeStyle.overrideI(it.editorGen.diagram)»
public java.util.List<«nodeDescriptor.qualifiedClassName(it)»> getSemanticChildren(org.eclipse.gmf.runtime.notation.View view) {
return «className(it)».getSemanticChildren(view);
}
«generatedMemberComment»
«xptCodeStyle.overrideI(it.editorGen.diagram)»
public java.util.List<«linkDescriptor.qualifiedClassName(it)»> getContainedLinks(org.eclipse.gmf.runtime.notation.View view) {
return «className(it)».getContainedLinks(view);
}
«generatedMemberComment»
«xptCodeStyle.overrideI(it.editorGen.diagram)»
public java.util.List<«linkDescriptor.qualifiedClassName(it)»> getIncomingLinks(org.eclipse.gmf.runtime.notation.View view) {
return «className(it)».getIncomingLinks(view);
}
«generatedMemberComment»
«xptCodeStyle.overrideI(it.editorGen.diagram)»
public java.util.List<«linkDescriptor.qualifiedClassName(it)»> getOutgoingLinks(org.eclipse.gmf.runtime.notation.View view) {
return «className(it)».getOutgoingLinks(view);
}
};
'''
def additions(GenDiagramUpdater it) ''''''
}