summaryrefslogtreecommitdiffstats
path: root/rba.tool.editor/src/rba/tool/editor/linking/RBAModelLinker.xtend
blob: 2ceaf1559540d577584a83889505efb02deadb07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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);
	}
}