EMF Reverse Lookup / navigating unidirectional references bidirectional
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);
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
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();