com.ibm.db.models.db2.util
Class ReverseNavigationHelper

java.lang.Object
  extended by com.ibm.db.models.db2.util.ReverseNavigationHelper
Direct Known Subclasses:
DatabaseToRemoteServerHelper, TableToRemoteDataSetHelper

public class ReverseNavigationHelper
extends java.lang.Object

ReverseNavigationHelper

Helper to augment a one-way EMF relationship with a virtual inverse relationship that makes it possible to navigate the one-way relationship in the opposite direction. This can be useful in cases where you wish to define a two-way relationship between classes that come from two different EMF models, but you only have authority to modify one of the models. In this situation you could create an explicit one-way EMF relationship from the class in your model to a class that belongs to the read-only model, and then you could establish a virtual inverse relationship that would allow you to write code that navigates in the inverse direction.

In order to use this helper to define a virtual inverse relationship, a client must do the following:

  1. Create a singleton instance of a ReverseNavigationHelper.InverseAdapter. This instance has state that identifies the EReference object that defines the one-way relationship and also a flag to indicate whether the virtual inverse relationship has a cardinality of SINGLE or MULTIPLE.

    For example, if the EMF package MyPackage has a one-way relationship called foo from class SourceClass to class TargetClass, and you wish the virtual inverse relationship to have a cardinality of SINGLE, you could define this singleton adapter as follows:

    protected static final EReference fooRef = MyPackage.eINSTANCE.getSourceClass_Foo(); public static final InverseAdapter INVERSE_FOO_ADAPTER = new InverseAdapter(fooRef, SINGLE);

  2. Make sure that the singleton instance is attached to every potential source object at the time each source object is created.

    There are different ways that this can be done in EMF. For instance, you can override the appropriate create method in the generated FactoryImpl for the package. Another way is that an AdapterFactory may be created and registered for objects that require source adapters.

  3. Anywhere it is necessary to navigate from the target object back to the source object, use the singleton instance of TargetAdapter created in step 1 to invoke the method ReverseNavigationHelper.InverseAdapter.getOppositeEnd(Notifier). The argument to this method is the target of the one-way EMF relationship (i.e. it is the source of the virtual inverse relationship.) The value returned by this method is the source of the one-way EMF relationship (i.e. it is the target of the virtual inverse relationship.)

    You may find it useful to provide a static convenience get method for the virtual inverse relationship. This convenience method could hide the singleton instance of the InverseAdapter and also cast the result of getOppositeEnd to be the appropriate type. So, for example, given the one-way relationship called foo described above, you may wish to define the following convenience method:

    public static SourceClass getInverseFoo(TargetClass t) { return (SourceClass) INVERSE_FOO_ADAPTER.getOppositeEnd(t); }

    Note, if we had chosen to define the virtual inverse relationship to be MULTIPLE instead of SINGLE, the convienience method would be

    public static EList getInverseFoo(TargetClass t) { return (EList) INVERSE_FOO_ADAPTER.getOppositeEnd(t); }

Usage Notes

Implementation Notes

As stated above, the helper requires that a singleton instance of InverseAdapter be attached to every potential source object. This adapter listens for changes to the specified one-way relationship. Whenever a target object is added to this relationship, another adapter called a TargetAdapter is created and attached to the target object. There is a separate instance of TargetAdapter for each instance of the target object. This adapter has state that includes the source object (or a list of source objects, depending on the inverse cardinality.) This TargetAdapter class is completely hidden from the client. The implementation of the InverseAdpater#getOppositeEnd method interogates the TargetAdapter and returns the object at the other end of the virtual inverse relationship.

Whenever the InverseAdapter processes a SET or ADD event that involves a proxy reference, the proxy will automatically be resolved. This will ensure that any new TargetAdapter that needs to be created will be attached to the resolved target object rather than to the proxy for the target object.

The InverseAdapter also listens for changes that remove a target object from the specified one-way relationship. When an UNSET or REMOVE event is processed, the corresponding targetAdapter will be updated as needed.


Nested Class Summary
static class ReverseNavigationHelper.InverseAdapter
          A InverseAdapter may be attached to any EObject that is the source of a one-way EMF relationship.
 
Field Summary
static int MULTIPLE
          MULTIPLE is used when constructing a ReverseNavigationHelper.InverseAdapter to specify that the cardinality of the source object is many.
static int SINGLE
          SINGLE is used when constructing a ReverseNavigationHelper.InverseAdapter to specify that the cardinality of the source object is 1.
 
Constructor Summary
ReverseNavigationHelper()
           
 
Method Summary
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SINGLE

public static final int SINGLE
SINGLE is used when constructing a ReverseNavigationHelper.InverseAdapter to specify that the cardinality of the source object is 1.

See Also:
Constant Field Values

MULTIPLE

public static final int MULTIPLE
MULTIPLE is used when constructing a ReverseNavigationHelper.InverseAdapter to specify that the cardinality of the source object is many.

See Also:
Constant Field Values
Constructor Detail

ReverseNavigationHelper

public ReverseNavigationHelper()