org.eclipse.ocl.ecore.opposites
Class DefaultOppositeEndFinder

java.lang.Object
  extended by org.eclipse.ocl.ecore.opposites.DefaultOppositeEndFinder
All Implemented Interfaces:
OppositeEndFinder

public class DefaultOppositeEndFinder
extends java.lang.Object
implements OppositeEndFinder

Opposite references declared by the annotation detail EcoreEnvironment#PROPERTY_OPPOSITE_ROLE_NAME_KEY on an EAnnotation with source EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0 are retrieved by scanning and caching the Ecore packages that this opposite end finder is aware of at the time of the request. The set of those packages is taken to be the set of EPackages resolved by an EPackage.Registry provided to #getInstance(Registry), or the default EPackage.Registry otherwise. In particular, this won't load any Ecore bundles not yet loaded.

This also means that with this implementation of the OppositeEndFinder interface it is necessary to resolve a package in the registry on which this opposite end finder is based before issuing a request expecting to find hidden opposites from that package. This can, e.g., be triggered by calling EPackage.Registry#getEPackage(String) for the package's URI.

Navigation across those references is performed either by EObject.eContainer() in case of containment references or by looking for an ECrossReferenceAdapter along the containment hierarchy of the source object from which to start the navigation. Only if such an adapter is registered along the composition/containment hierarchy can the navigation be performed successfully. Note also that this will only consider references that have been currently loaded which can give rather random results. For more predictable results, an implementation should be used that relies on a well-defined query scope and a corresponding query engine.

Instances of this class are cached in a WeakHashMap, keyed by the EPackage.Registry object used for #getInstance(Registry). This means that if the registry gets eligible for garbage collection then so will this opposite end finder.

Since:
3.1
Author:
Axel Uhl

Field Summary
 
Fields inherited from interface org.eclipse.ocl.ecore.opposites.OppositeEndFinder
PROPERTY_OPPOSITE_ROLE_NAME_KEY
 
Constructor Summary
DefaultOppositeEndFinder(org.eclipse.emf.ecore.EPackage.Registry registry)
           
 
Method Summary
 void findOppositeEnds(org.eclipse.emf.ecore.EClassifier classifier, java.lang.String name, java.util.List<org.eclipse.emf.ecore.EReference> ends)
          Looks for EReferences whose type is classifier or any of classifier's super types and that owns an annotation with source EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0 containing a detail entry with key EcoreEnvironment#PROPERTY_OPPOSITE_ROLE_NAME_KEY and the value equalling name.
 java.util.Set<org.eclipse.emf.ecore.EObject> getAllInstancesSeeing(org.eclipse.emf.ecore.EClass cls, org.eclipse.emf.common.notify.Notifier context)
          This default implementation uses an AllInstancesContentAdapter on context's root context (see AllInstancesContentAdapter.getInstanceForRootContextOf(Notifier)) which is created lazily if it isn't set yet.
 java.util.Set<org.eclipse.emf.ecore.EObject> getAllInstancesSeenBy(org.eclipse.emf.ecore.EClass cls, org.eclipse.emf.common.notify.Notifier context)
          Finds all instances of class cls and all its subclasses that are visible from context.
 java.util.Map<java.lang.String,org.eclipse.emf.ecore.EReference> getAllOppositeEnds(org.eclipse.emf.ecore.EClassifier classifier)
          Finds all EReferences whose type is classifier or any of classifier's super types and that own an annotation with source EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0 containing a detail entry with key EcoreEnvironment#PROPERTY_OPPOSITE_ROLE_NAME_KEY.
static DefaultOppositeEndFinder getInstance()
          Scans all packages from the default EPackage.Registry that have already been loaded.
static DefaultOppositeEndFinder getInstance(org.eclipse.emf.ecore.EPackage.Registry registry)
          Scans all packages from the registry specified that have already been loaded.
 java.util.Collection<org.eclipse.emf.ecore.EObject> navigateOppositePropertyWithBackwardScope(org.eclipse.emf.ecore.EReference property, org.eclipse.emf.ecore.EObject target)
          Reverse-navigates the property starting at target.
 java.util.Collection<org.eclipse.emf.ecore.EObject> navigateOppositePropertyWithForwardScope(org.eclipse.emf.ecore.EReference property, org.eclipse.emf.ecore.EObject target)
          If on the target or any of its containers up to the ResourceSet there is a ECrossReferenceAdapter registered, uses it for navigating property in reverse.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DefaultOppositeEndFinder

public DefaultOppositeEndFinder(org.eclipse.emf.ecore.EPackage.Registry registry)
Method Detail

getInstance

public static DefaultOppositeEndFinder getInstance()
Scans all packages from the default EPackage.Registry that have already been loaded. While this is convenient, please keep in mind that this may be fairly random a definition of a package set as loading of packages happens on demand. You will get more predictable results using #getInstance(Set).


getInstance

public static DefaultOppositeEndFinder getInstance(org.eclipse.emf.ecore.EPackage.Registry registry)
Scans all packages from the registry specified that have already been loaded. While this is convenient, please keep in mind that this may be fairly random a definition of a package set as loading of packages happens on demand. You will get more predictable results using #getInstance(Set).


findOppositeEnds

public void findOppositeEnds(org.eclipse.emf.ecore.EClassifier classifier,
                             java.lang.String name,
                             java.util.List<org.eclipse.emf.ecore.EReference> ends)
Description copied from interface: OppositeEndFinder
Looks for EReferences whose type is classifier or any of classifier's super types and that owns an annotation with source EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0 containing a detail entry with key EcoreEnvironment#PROPERTY_OPPOSITE_ROLE_NAME_KEY and the value equalling name. Such references are added to ends.

Specified by:
findOppositeEnds in interface OppositeEndFinder

getAllOppositeEnds

public java.util.Map<java.lang.String,org.eclipse.emf.ecore.EReference> getAllOppositeEnds(org.eclipse.emf.ecore.EClassifier classifier)
Description copied from interface: OppositeEndFinder
Finds all EReferences whose type is classifier or any of classifier's super types and that own an annotation with source EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0 containing a detail entry with key EcoreEnvironment#PROPERTY_OPPOSITE_ROLE_NAME_KEY. The value of the annotation detail is entered into the resulting map as a key, the EReference on which the annotation was found is entered into the result map as the corresponding value.

Specified by:
getAllOppositeEnds in interface OppositeEndFinder
Returns:
a non-null map of all "hidden references" accessible from classifier together with their corresponding forward references

navigateOppositePropertyWithForwardScope

public java.util.Collection<org.eclipse.emf.ecore.EObject> navigateOppositePropertyWithForwardScope(org.eclipse.emf.ecore.EReference property,
                                                                                                    org.eclipse.emf.ecore.EObject target)
If on the target or any of its containers up to the ResourceSet there is a ECrossReferenceAdapter registered, uses it for navigating property in reverse. In this case, a non- null collection is returned which contains those EObjects on which navigating property leads to target. The "forward" scope is just whatever the ECrossReferenceAdapter sees that is expected to be registered on target

Specified by:
navigateOppositePropertyWithForwardScope in interface OppositeEndFinder
Parameters:
target - must be a non-null EObject

navigateOppositePropertyWithBackwardScope

public java.util.Collection<org.eclipse.emf.ecore.EObject> navigateOppositePropertyWithBackwardScope(org.eclipse.emf.ecore.EReference property,
                                                                                                     org.eclipse.emf.ecore.EObject target)
Description copied from interface: OppositeEndFinder
Reverse-navigates the property starting at target. As a result, one or more objects may result such that when navigating property from any of those, then target will be among the results. If no such objects are found, it is permissible for an implementation to return null. As scope used for this query one should be used by implementers that contains everything that can see target.

Specified by:
navigateOppositePropertyWithBackwardScope in interface OppositeEndFinder

getAllInstancesSeeing

public java.util.Set<org.eclipse.emf.ecore.EObject> getAllInstancesSeeing(org.eclipse.emf.ecore.EClass cls,
                                                                          org.eclipse.emf.common.notify.Notifier context)
This default implementation uses an AllInstancesContentAdapter on context's root context (see AllInstancesContentAdapter.getInstanceForRootContextOf(Notifier)) which is created lazily if it isn't set yet. Note that for larger resource sets with many resources and elements this won't scale very well as all resources will be scanned for elements conforming to cls. Also, no scoping other than tracing to the root context based on context is performed.

Specified by:
getAllInstancesSeeing in interface OppositeEndFinder
Returns:
a non-null set

getAllInstancesSeenBy

public java.util.Set<org.eclipse.emf.ecore.EObject> getAllInstancesSeenBy(org.eclipse.emf.ecore.EClass cls,
                                                                          org.eclipse.emf.common.notify.Notifier context)
Description copied from interface: OppositeEndFinder
Finds all instances of class cls and all its subclasses that are visible from context.

Specified by:
getAllInstancesSeenBy in interface OppositeEndFinder
Returns:
a non-null set