diff options
Diffstat (limited to 'rba.tool.editor/src/rba/tool/editor/linking')
-rw-r--r-- | rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinker.xtend | 87 | ||||
-rw-r--r-- | rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinkingService.xtend | 66 |
2 files changed, 153 insertions, 0 deletions
diff --git a/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinker.xtend b/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinker.xtend new file mode 100644 index 0000000..2ceaf15 --- /dev/null +++ b/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinker.xtend @@ -0,0 +1,87 @@ +package rba.tool.editor.linking + +import java.util.ArrayList +import java.util.Iterator +import java.util.List +import javax.inject.Inject +import org.eclipse.emf.common.util.AbstractTreeIterator +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EReference +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.xtext.EcoreUtil2 +import org.eclipse.xtext.linking.impl.DefaultLinkingService +import org.eclipse.xtext.linking.lazy.LazyLinker +import org.eclipse.xtext.nodemodel.INode +import rba.core.ObjectReference +import rba.tool.editor.rbaEditorModel.MemberFeatureReference +import rba.tool.editor.util.RBAModelEditorToolUtil + +class RBAModelLinker extends LazyLinker { + + @Inject extension DefaultLinkingService linkingService + + override protected clearReference(EObject obj, EReference ref) { + if(RBAModelEditorToolUtil.isSkippedSyntax(obj, ref)) { + return; + } + super.clearReference(obj, ref); + } + + override protected createProxy(EObject obj, INode node, EReference eRef) { + val EObject result = getLinkedObject(obj, node, eRef); + if(eRef.EOpposite !== null && (result !== null && result.eClass.EAllSuperTypes.contains(eRef.EReferenceType))) { + val Resource objResource = obj.eResource(); + val Resource rslResource = result.eResource(); + if(!equals(objResource.URI, rslResource.URI)) { + return result; + } + } + + return super.createProxy(obj, node, eRef); + } + + override protected getAllLinkableContents(EObject model) { + val AbstractTreeIterator<EObject> result = new AbstractTreeIterator<EObject>(model) { + override public Iterator<EObject> getChildren(Object object) { + val List<EObject> contents = new ArrayList<EObject>(); + if(object instanceof MemberFeatureReference) { + // do nothing + } else { + val temp = (object as EObject).eContents(); + for (eObject : temp) { + if(eObject instanceof MemberFeatureReference) { + contents.addAll(EcoreUtil2.getAllContentsOfType(eObject, ObjectReference)); + } + contents.add(eObject); + } + } + return contents.iterator(); + } + }; + + return result; + } + + def private EObject getLinkedObject(EObject obj, INode node, EReference eRef) { + val linkedObjects = linkingService.getLinkedObjects(obj, eRef, node); + if(linkedObjects.size == 1) { + val linkedObject = linkedObjects.get(0); + if(linkedObject.eIsProxy) { + return EcoreUtil.resolve(linkedObject, obj.eResource); + } else { + return linkedObject; + } + } + return null; + } + + def private boolean equals(URI uri1, URI uri2) { + if(uri1 === null || uri2 === null) { + return false; + } + + return uri1.equals(uri2); + } +} diff --git a/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinkingService.xtend b/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinkingService.xtend new file mode 100644 index 0000000..f3d6a52 --- /dev/null +++ b/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinkingService.xtend @@ -0,0 +1,66 @@ +package rba.tool.editor.linking + +import com.google.inject.Inject +import java.util.Collections +import org.apache.log4j.Logger +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EReference +import org.eclipse.xtext.EcoreUtil2 +import org.eclipse.xtext.linking.impl.DefaultLinkingService +import org.eclipse.xtext.linking.impl.IllegalNodeException +import org.eclipse.xtext.naming.IQualifiedNameConverter +import org.eclipse.xtext.nodemodel.INode +import rba.core.ObjectReference +import rba.core.Package +import rba.core.RBACorePackage +import rba.core.RuleObject + +class RBAModelLinkingService extends DefaultLinkingService { + + private static final Logger logger = Logger.getLogger(RBAModelLinkingService); + + @Inject + private IQualifiedNameConverter qualifiedNameConverter; + + override getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException { + val requiredType = ref.getEReferenceType(); + if(requiredType === null) { + return Collections.<EObject>emptyList(); + } + val crossRefString = getCrossRefNodeAsString(node); + if(crossRefString === null || crossRefString.equals("")) { + return Collections.<EObject>emptyList(); + } + if(logger.isDebugEnabled()) { + logger.debug("before getLinkedObjects: node: '" + crossRefString + "'"); + } + + if(context instanceof ObjectReference && ref === RBACorePackage.Literals.OBJECT_REFERENCE__REF_OBJECT && crossRefString.equals("this")) { + val containers = EcoreUtil2.getAllContainers(context).filter [ c | + c instanceof RuleObject && c.eContainer instanceof Package + ].toList; + if(containers !== null && containers.size === 1) { + return Collections.singletonList(containers.get(0)); + } else { + return Collections.emptyList(); + } + } + + val scope = getScope(context, ref); + if(scope === null) { + throw new AssertionError( + "Scope provider " + scopeProvider.getClass().getName() + " must not return null for context " + context + ", reference " + ref + "! Consider to return IScope.NULLSCOPE instead."); + } + val qualifiedLinkName = qualifiedNameConverter.toQualifiedName(crossRefString); + val eObjectDescription = scope.getSingleElement(qualifiedLinkName); + if(logger.isDebugEnabled()) { + logger.debug("after getLinkedObjects: node: '" + crossRefString + "' result: " + eObjectDescription); + } + if(eObjectDescription === null) { + return Collections.emptyList(); + } + val result = eObjectDescription.getEObjectOrProxy(); + return Collections.singletonList(result); + } + +} |