EMF Reverse Lookup / navigating unidirectional references bidirectional
Through ECrossReferenceAdapter
Looking up the non-navigable references requires the usage of cross referencers in EMF.
Problem: Although using the ECrossReferenceAdapter and assigning it to a Resource, the reverse lookup does not work.
Solution: Use a EMF ResourceSet instead of a EMF Resource. Only ResourceSets enable reverse lookups.
ResourceSet resourceSet = new ResourceSetImpl();
Resource emfResource = resourceSet.createResource(fileURI); //use the resource set to retrieve the resource
The cross reference adapter listens to any changes of references and updates itself. Unlike the cross referencer available from EcoreUtil (using EcoreUtil.CrossReferencer.find(object);
), the performance of the ECroosReferenceAdapter is much better since it is not traversing the whole EMF tree per request.
// Ensure that the cross reference adapter is called at the beginning.
ECrossReferenceAdapter adapter = new ECrossReferenceAdapter();
resourceSet.eAdapters().add(adapter);
Then look up the reverse references of the associations:
Collection<Setting> settings = adapter.getInverseReferences(eObjectToGetCrossReferencesFor, true);
The settings
collection then allows to access the EStructuralFeatures
of the passed eObjectToGetCrossReferencesFor
using the iterator. The cross reference is of the type EReference
which extends EStructuralFeature
.
Through EObject.eContainer (for containment references)
If you want to navigate unidirectional containment references you can use [EObjectInstance].eContainer() to get the containing EObject. However, you have to cast the container by yourself to use it.
Example (Context is Parent <<containment>> -1--*-> Child):
Parent parent = (Parent) child.eContainer();