2015-05-10

← Older revision

Revision as of 17:47, 10 May 2015

Line 26:

Line 26:

The adapt package provides a modernized interpretation of the Eclipse Core Runtime's [http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2FIAdaptable.html IAdaptable], providing the following enhancements:

The adapt package provides a modernized interpretation of the Eclipse Core Runtime's [http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2FIAdaptable.html IAdaptable], providing the following enhancements:



# Adapters may be registered and retrieved by means of a TypeToken key as an alternative to a Class key, which ensures that adapters with parameterized types may also be registered and retrieved in a type-safe manner, not only via their raw type. For instance, an adapter instance ''a1'' of parameterized type ''A<T1>'' and an instance ''a2'' of type ''A<T2>'' can both be registered at an IAdaptable. The [[GEF/GEF4/MVC GEF4 MVC]] component makes use of this intensively, when registering providers, i.e. a Provider<IGeometry> and a Provider<IFXAnchor> can
now
both be registered at an
IAdaptable
simultaneously.

+

# Adapters may be registered and retrieved by means of a TypeToken key as an alternative to a Class key, which ensures that adapters with parameterized types may also be registered and retrieved in a type-safe manner, not only via their raw type. For instance, an adapter instance ''a1'' of parameterized type ''A<T1>'' and an instance ''a2'' of type ''A<T2>'' can both be registered at an
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
. The [[GEF/GEF4/MVC GEF4 MVC]] component makes use of this intensively, when registering providers, i.e. a Provider<IGeometry> and a Provider<IFXAnchor> can both be registered at an
IVisualPart
simultaneously.



# Adapters may (optionally) be registered and retrieved by providing an additional role key, which allows to register multiple adapters of the same type (using different roles) at an IAdaptable. For instance, adapter instances ''a1'' and ''a2'' of type ''A'' can both be registered at an
IAdaptable
using different roles. The [[GEF/GEF4/MVC GEF4 MVC]] component again makes use of this, when registering providers. Different geometry providers (Provider<IGeometry>) are e.g. registered for selection and hover feedback, by registering respective providers with respective roles.

+

# Adapters may (optionally) be registered and retrieved by providing an additional role key, which allows to register multiple adapters of the same type (using different roles) at an
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
. For instance, adapter instances ''a1'' and ''a2'' of type ''A'' can both be registered at an
adaptable
using different roles. The [[GEF/GEF4/MVC GEF4 MVC]] component again makes use of this, when registering providers. Different geometry providers (Provider<IGeometry>) are e.g. registered for selection and hover feedback, by registering respective providers with respective roles.



# Adapters may request a back-reference to the respective IAdaptable they get registered at, by implementing a respective back-interface (IAdaptable.Bound). Again, this is intensively used within [[GEF/GEF4/MVC GEF4 MVC]], where an IBehavior or IPolicy for instance needs to be aware of the host IVisualPart it is registered at.

+

# Adapters may request a back-reference to the respective
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
they get registered at, by implementing a respective back-interface (
[[GEF/GEF4/Common#
IAdaptable.Bound
| IAdaptable.Bound]]
). Again, this is intensively used within [[GEF/GEF4/MVC GEF4 MVC]], where an IBehavior or IPolicy for instance needs to be aware of the host IVisualPart it is registered at.

# IAdaptable provides support for registering property change listeners, to be notified whenever adapters are registered or unregistered.

# IAdaptable provides support for registering property change listeners, to be notified whenever adapters are registered or unregistered.



Besides the IAdaptable, IAdaptable.Bound, and AdapterKey abstractions that formalize the modernized adaptable pattern, the package also provides a supporting class (AdaptableSupport) to implement IAdaptable in compliance with its contract, as well as a standalone implementation (AdapterStore)
of an IAdaptable
.

+

Besides the
[[GEF/GEF4/Common#
IAdaptable,
AdapterKey | IAdaptable]], [[GEF/GEF4/Common#
IAdaptable.Bound
| IAdaptable.Bound]]
, and
[[GEF/GEF4/Common#IAdaptable,
AdapterKey
| AdapterKey]]
abstractions that formalize the modernized adaptable pattern, the package also provides a supporting class (
[[GEF/GEF4/Common#
AdaptableSupport
| AdaptableSupport]]
) to implement
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
in compliance with its contract, as well as a standalone implementation (
[[GEF/GEF4/Common#
AdapterStore
| AdapterStore]]
).

=== IAdaptable, AdapterKey ===

=== IAdaptable, AdapterKey ===



The first two enhancements listed above are realized by the option to register and retrieve adapters via an AdapterKey, which combines a type key (Class or TypeToken) with an (optional) role. Having the option to use a TypeToken instead of a simple Class key, enables the type-safe registration of adapters with parameterized types. The combination with an additional (optional) role enables that multiple adapters of the same type may be registered at an
Adaptable
.

+

The first two enhancements listed above are realized by the option to register and retrieve adapters via an
[[GEF/GEF4/Common#IAdaptable, AdapterKey |
AdapterKey
]]
, which combines a type key (Class or TypeToken) with an (optional) role. Having the option to use a TypeToken instead of a simple Class key, enables the type-safe registration of adapters with parameterized types. The combination with an additional (optional) role enables that multiple adapters of the same type may be registered at an
[[GEF/GEF4/Common#IAdaptable, AdapterKey | IAdaptable]]
.

The 'traditional' getAdapter(Class<? super T>) method now is just a convenience operation that will retrieve the adapter registered with the respective Class key and the default role (or the only adapter registered under the given Class key, if there is only one adapter for that type key).

The 'traditional' getAdapter(Class<? super T>) method now is just a convenience operation that will retrieve the adapter registered with the respective Class key and the default role (or the only adapter registered under the given Class key, if there is only one adapter for that type key).

Line 60:

Line 60:



To formalize support for notifying listeners about registration and unregistration of adapters, IAdaptable furthermore extends [[GEF/GEF4/Common#IPropertyChangeNotifier | IPropertyChangeNotifier]], which provides capabilities for registering and unregistering respective listeners.

+

To formalize support for notifying listeners about registration and unregistration of adapters,
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
furthermore extends [[GEF/GEF4/Common#IPropertyChangeNotifier | IPropertyChangeNotifier]], which provides capabilities for registering and unregistering respective listeners.

=== IAdaptable.Bound ===

=== IAdaptable.Bound ===



To formalize that an adapter may need to obtain a back reference to an IAdaptable, the IAdaptable.Bound interface was introduced. If an adapter implements this interface, the adaptable at which the adapter is registered is responsible of providing a back reference to the adapter as follows:

+

To formalize that an adapter may need to obtain a back reference to an
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
, the
[[GEF/GEF4/Common#IAdaptable.Bound |
IAdaptable.Bound
]]
interface was introduced. If an adapter implements this interface, the adaptable at which the adapter is registered is responsible of providing a back reference to the adapter as follows:

<source lang="java">

<source lang="java">

Line 87:

Line 87:

=== AdaptableSupport ===

=== AdaptableSupport ===



To enforce that implementers of IAdaptable properly follow the above outlined contract, the package furthermore provides an AdaptableSupport class, which does not formally implement the IAdaptable interface but provides implementations for all its methods and can thus be simply used as a delegate, as follows:

+

To enforce that implementers of IAdaptable properly follow the above outlined contract, the package furthermore provides an AdaptableSupport class, which does not formally implement the
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
interface but provides implementations for all its methods and can thus be simply used as a delegate, as follows:

<source lang="java">

<source lang="java">

Line 105:

Line 105:



It needs to be provided with a [http://docs.oracle.com/javase/7/docs/api/index.html?java/beans/PropertyChangeSupport.html PropertyChangeSupport], which will be used to notify listeners about registration and unregistration of adapters. In case the adaptable, by which it is used as a delegate, is also [[GEF/GEF4/Common#IActivatable | IActivatable]], it will ensure that all IActivatable adapters are properly activated/deactivated when being registered/unregistered dependent on the active state of the adaptable at that moment.

+

It needs to be provided with a [http://docs.oracle.com/javase/7/docs/api/index.html?java/beans/PropertyChangeSupport.html PropertyChangeSupport], which will be used to notify listeners about registration and unregistration of adapters. In case the adaptable, by which it is used as a delegate, is also [[GEF/GEF4/Common#IActivatable | IActivatable]], it will ensure that all
[[GEF/GEF4/Common#
IActivatable
| IActivatable]]
adapters are properly activated/deactivated when being registered/unregistered dependent on the active state of the adaptable at that moment.

=== AdapterStore ===

=== AdapterStore ===



The package furthermore provides an AdaptableStore, which can be used as a standalone IAdaptable.

+

The package furthermore provides an AdaptableStore, which can be used as a standalone
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
.

== Dispose  ==

== Dispose  ==

Line 122:

Line 122:

[[File:GEF4-Common-inject-adaptermap.png|969px]]

[[File:GEF4-Common-inject-adaptermap.png|969px]]



This package contains [https://github.com/google/guice Google Guice]-based support for injection of adapters
to
[[GEF/GEF4/Common#IAdaptable, AdapterKey | IAdaptable]]
s
. That is, if an IAdaptable implementation provides
a
method with a single Map<AdapterKey<?>, Object> parameter that is annotated with a respective inject annotation (@AdapterMap), and if respective adapter bindings are provided within a Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module], adapter instances can automatically be injected into instances of the IAdaptable by means of a specific [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/MembersInjector.html MembersInjector]. It needs to be pointed out that respective adapter bindings are evaluated polymorphically, i.e. a concrete
IAdaptable
will also be injected with all adapters that registered for super types of it.

+

This package contains [https://github.com/google/guice Google Guice]-based support for injection of adapters
into an
[[GEF/GEF4/Common#IAdaptable, AdapterKey | IAdaptable]]. That is, if an
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
implementation provides
an [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Inject.html @Inject]-annotated
method with a single Map<AdapterKey<?>, Object> parameter that is annotated with a respective inject annotation (@AdapterMap), and if respective adapter bindings are provided within a Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module], adapter instances can automatically be injected into instances of the
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
by means of a specific [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/MembersInjector.html MembersInjector]. It needs to be pointed out that respective adapter bindings are evaluated polymorphically, i.e. a concrete
adaptable
will also be injected with all adapters that registered for super types of it.

=== AdapterMapInjectionSupport, AdaptableTypeListener, AdapterMapInjector ===

=== AdapterMapInjectionSupport, AdaptableTypeListener, AdapterMapInjector ===



To enable injection of adapters to IAdaptables, a specific [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/spi/TypeListener.html TypeListener] (AdaptableTypeListener) needs to be registered in the Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module]. To ensure this is
properly
done, a respective support [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module] is provided, namely AdapterMapInjectionSupport, which can easily be integrated into a custom [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module] as follows:

+

To enable injection of adapters to IAdaptables, a specific [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/spi/TypeListener.html TypeListener] (AdaptableTypeListener) needs to be registered in the Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module]. To ensure this is done
properly
, a respective support [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module] is provided, namely AdapterMapInjectionSupport, which can easily be integrated into a custom [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module] as follows:

<source lang="java">

<source lang="java">

Line 144:

Line 144:

=== AdapterMap, AdapterMaps ===

=== AdapterMap, AdapterMaps ===



The @AdapterMap annotation is used in two ways. First, it is used to specify respective adapter map-bindings within the Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module]. Second, it is used to specify the injection point, i.e. the method within the IAdaptable implementation that should be injected with adapters.

+

The @AdapterMap annotation is used in two ways. First, it is used to specify respective adapter map-bindings within the Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module]. Second, it is used to specify the injection point, i.e. the method within the
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
implementation that should be injected with adapters.

Specifying the injection point within a respective IAdaptable implementation is achieved by means of a method, which is marked for injection by means of an [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Inject.html @Inject] annotation, and furthermore provides a single Map<AdapterKey<?>, Object> parameter that is annotated with @AdapterMap as follows:

Specifying the injection point within a respective IAdaptable implementation is achieved by means of a method, which is marked for injection by means of an [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Inject.html @Inject] annotation, and furthermore provides a single Map<AdapterKey<?>, Object> parameter that is annotated with @AdapterMap as follows:

Line 186:

Line 186:



When adapter map injection is properly enabled in the [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module], all suitable IAdaptable instances that are created through an [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Injector.html Injector] will be injected. To this extend, the @AdapterMap bindings can be compared to the Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/name/Named.html @Named] bindings, only that a 'Class' instead of a 'String' key is used. However, @AdapterMap bindings are more powerful, as they are evaluated polymorphically. That is, if an adapter map binding is specified for a specific IAdaptable type, let's say 'A', it will be evaluated for instances of all subtypes of 'A' as well, as long as they are suitable for injection (i.e. they directly or via inheritance provide a respective method for adapter map injection). This is a very powerful mechanism that is used intensively by the [[GEF/GEF4/MVC | GEF4 MVC]] component. It allows to register certain adapters already for some abstract base type, so that each concrete sub-type will be injected with a respective adapter instance.

+

When adapter map injection is properly enabled in the [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Module.html Module], all suitable IAdaptable instances that are created through an [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Injector.html Injector] will be injected. To this extend, the @AdapterMap bindings can be compared to the Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/name/Named.html @Named] bindings, only that a 'Class' instead of a 'String' key is used. However, @AdapterMap bindings are more powerful, as they are evaluated polymorphically. That is, if an adapter map binding is specified for a specific
[[GEF/GEF4/Common#
IAdaptable
, AdapterKey | IAdaptable]]
type, let's say 'A', it will be evaluated for instances of all subtypes of 'A' as well, as long as they are suitable for injection (i.e. they directly or via inheritance provide a respective method for adapter map injection). This is a very powerful mechanism that is used intensively by the [[GEF/GEF4/MVC | GEF4 MVC]] component. It allows to register certain adapters already for some abstract base type, so that each concrete sub-type will be injected with a respective adapter instance.

=== AdaptableScope, AdaptableScopes ===

=== AdaptableScope, AdaptableScopes ===



In addition to basic injection support for adapters, the package also provides support for scoping the to be injected adapter instances by means of a dedicated Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Scope.html Scope] (AdaptableScope).

+

In addition to basic injection support for adapters, the package also provides support for scoping the to be injected adapter instances by means of a dedicated Guice [http://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Scope.html Scope] (
[[GEF/GEF4/Common#
AdaptableScope
| AdaptableScope]]
).

[[File:GEF4-Common-inject-adaptablescopes.png|763px]]

[[File:GEF4-Common-inject-adaptablescopes.png|763px]]

Show more