|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectcom.ibm.db.models.db2.util.ReverseNavigationHelper
public class ReverseNavigationHelper
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:
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:
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.
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:
Note, if we had chosen to define the virtual inverse relationship to be MULTIPLE
instead of SINGLE
, the convienience method would be
Usage Notes
setOppositeEnd
method.
Also note that in the case where the inverse cardinality is
MULTIPLE
, the EList that is returned from getOppositeEnd
in unmodifiable.
Thus, the only way to create an instance of a virtual inverse relationship is to create an instance of the corresponeding
one-way EMF relationship.
SINGLE
, if a given target object is already has a
source object, the relationship on the old source object will be automatically updated to remove the target.
For example, if s1
and s2
are instances of SourceClass
(from the above
example)
and t1
is an instance of TargetClass
,
the following code fragment:
will print null.
In other words, the fact that the virtual inverse relationship
from TargetClass
to SourceClass
has a cardinality of SINGLE
,
introduces a side-effect to the generated set method that did not occur when the virtual inverse relationship was
not present.
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 |
---|
public static final int SINGLE
SINGLE
is used when constructing a ReverseNavigationHelper.InverseAdapter
to specify that the cardinality
of the source object is 1.
public static final int MULTIPLE
MULTIPLE
is used when constructing a ReverseNavigationHelper.InverseAdapter
to specify that the cardinality
of the source object is many.
Constructor Detail |
---|
public ReverseNavigationHelper()
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |