[
https://issues.apache.org/jira/browse/FELIX-5941?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Pierre De Rop resolved FELIX-5941.
----------------------------------
Resolution: Fixed
committed in revision 1842034.
> DM APi enhancements
> -------------------
>
> Key: FELIX-5941
> URL: https://issues.apache.org/jira/browse/FELIX-5941
> Project: Felix
> Issue Type: Improvement
> Components: Dependency Manager
> Reporter: Pierre De Rop
> Assignee: Pierre De Rop
> Priority: Minor
> Fix For: org.apache.felix.dependencymanager-r12
>
>
> in [https://github.com/pderop/dm.enhanced,] some enhancements have been done
> regarding the dm API, and the intent of this issue is to merge the
> improvements into the felix trunk:
> * the api to define aspects and adapters have been reworked (but dm API
> remains {{backward compatible}})
> * you can now declare multiple property type interfaces when using
> Configuration Dependency or Factory Components (this was needed to implement
> the enhancements for the annotations)
> * configuration dependency using metatypes can now declare property types
> * Allow to specify if propagated configuration dependencies must override
> service service properties (it was not possible to override service
> properties with propagated service properties so far)
> * Added the following signatures in Component interface:
> ** setInterface(Class serviceName, Dictionary properties)
> ** setInterface(Class[] serviceNames, Dictionary properties)
> h3. *Aspect/Adapters Api enhancements*
> So far, aspects or adapters were defined using many methods from
> DependencyManager or DependencyActivatorBase classes:
> For example, in DependencyManager.java, we currently have many signatures
> {code:java}
> public class DependencyManager {
> public Component createAdapterService(Class<?> serviceInterface, String
> serviceFilter) {...}
> public Component createAdapterService(Class<?> serviceInterface, String
> serviceFilter, String autoConfig) {...}
> public Component createAdapterService(Class<?> serviceInterface, String
> serviceFilter, String add, String change, String remove) {...}
> public Component createAdapterService(Class<?> serviceInterface, String
> serviceFilter, String add, String change, String remove, String swap) {...}
> public Component createAdapterService(Class<?> serviceInterface, String
> serviceFilter, String autoConfig, Object callbackInstance, String add, String
> change, String remove, String swap, boolean propagate) {...}
>
> public Component createFactoryConfigurationAdapterService(String
> factoryPid, String update, boolean propagate) {...}
> public Component createFactoryConfigurationAdapterService(String
> factoryPid, String update, boolean propagate, Object callbackInstance) {...}
> public Component createFactoryConfigurationAdapterService(String
> factoryPid, String update, boolean propagate, Class<?> configType) {...}
> public Component createFactoryConfigurationAdapterService(String
> factoryPid, String update, boolean propagate, Object callbackInstance,
> Class<?> configType) {...}
> public Component createAdapterFactoryConfigurationService(String
> factoryPid, String update, boolean propagate,String heading, String desc,
> String localization, PropertyMetaData[] propertiesMetaData) {...}
>
> public Component createBundleAdapterService(int bundleStateMask, String
> bundleFilter, boolean propagate) {...}
> public Component createBundleAdapterService(int bundleStateMask, String
> bundleFilter, boolean propagate, Object callbackInstance, String add, String
> change, String remove) {...}
>
> public Component createResourceAdapterService(String resourceFilter,
> boolean propagate, Object callbackInstance, String callbackChanged) {...}
> public Component createResourceAdapterService(String resourceFilter,
> boolean propagate, Object callbackInstance, String callbackSet, String
> callbackChanged)
> public Component createResourceAdapterService(String resourceFilter,
> Object propagateCallbackInstance, String propagateCallbackMethod, Object
> callbackInstance, String callbackChanged) {...}
> public Component createResourceAdapterService(String resourceFilter,
> Object propagateCallbackInstance, String propagateCallbackMethod, Object
> callbackInstance, String callbackSet, String callbackChanged) {...}
>
> public Component createAspectService(Class<?> serviceInterface, String
> serviceFilter, int ranking, String autoConfig) {...}
> public Component createAspectService(Class<?> serviceInterface, String
> serviceFilter, int ranking) {...}
> public Component createAspectService(Class<?> serviceInterface, String
> serviceFilter, int ranking, String add, String change, String remove) {...}
> public Component createAspectService(Class<?> serviceInterface, String
> serviceFilter, int ranking, String add, String change, String remove, String
> swap) {...}
> public Component createAspectService(Class<?> serviceInterface, String
> serviceFilter, int ranking, Object callbackInstance, String add, String
> change, String remove, String swap) {...}{code}
> So, we have simplified the usage of the aspect/adapters like this: instead of
> having to use some of the many methods from the DependencyManager or
> DependencyActivatorBase, we have added some new interfaces for the aspect and
> adapters, and these interfaces are extending the Component interface. All
> other existing methods have been moved to
> DependencyManagerCompat/DependencyActivatorBaseCompat classes and the
> DependencyManager/DependencyActovatorBase classes are now extending the
> compat classes: this allows to simplify the reading of the javadocs for
> DependencyManager/DependencyActovatorBase.
> For example, let's first show how an factory pid component was declared so
> far (a factory pid component is one which can be instantiated multiple times
> using a "factory configuration" created using standard "configuration admin"
> service):
> {code:java}
> public class Activator extends DependencyActivatorBase {
> @Override
> public void init(BundleContext context, DependencyManager dm) throws
> Exception {
> dm.add(createFactoryConfigurationAdapterService("my.factory.pid",
> "updated", true, MyConfig.class)
> .setInterface(MyService.class.getName(), null)
> .setImplementation(MyServiceImpl.class)
> .add(createServiceDependency().setService(LogService.class)));
> }
> }{code}
> So, now, there is a new FactoryComponent interface which extends the
> Component interface and it contains all the various parameters used when
> declaring a factory pid component. So the example above becomes:
> {code:java}
> public class Activator extends DependencyActivatorBase {
> @Override
> public void init(BundleContext context, DependencyManager dm) throws
> Exception {
> dm.add(createFactoryComponent()
> .setFactoryPid("my.factory.pid")
> .setPropagate(true)
> .setConfigType(MyConfig.class)
> .setInterface(MyService.class.getName(), null)
> .setImplementation(MyServiceImpl.class)
> .add(createServiceDependency().setService(LogService.class)));
> }
> }{code}
> Now, we explain what the new interfaces look like: Indeed as you can imagine,
> there is an issue when you extend the Component interface, because the
> various Component setter methods return a Component type. So, what we would
> like is to be able to introduce a generic type in the Component interface ,
> and such generic type can then be used to allow the Component setter methods
> to return not the Component type, but instead return the aspect/adapter sub
> classes. This is what we have done, let's show a pseudo code, so you can
> understand how it works:
> First, the Component annotation have been reworked like this:
> {code:java}
> public interface Component<T extends Component<T>> {
> T setInterface(String service, Dictionary properties)
> T setImplementation(Object ob);
> ...
> }{code}
> As you can see the Component annotation is now using a recursive generic type
> which extends the Component interface. And now we have for example the
> following AdapterComponent interface which is defined like this:
> {code:java}
> public interface AdapterComponent extends Component<AdapterComponent> {
> AdapterComponent setAdaptee(Class<?> service, String filter);
> AdapterComponent setAdapteeCallbacks(String add, String change, String
> remove, String swap);
> ...
> }{code}
> So, now, an adapter component can be defined like this:
> {code:java}
> Component adapter = createAdapterComponent()
> .setAdaptee(Adaptee.class, "(foo=bar)")
> .setAdapteeCallbacks("setAdaptee", "changeAdaptee", null, null)
> .setImplementation(AdapterImpl.class)
> .setInterface(AdapterService.class, null)
> .add(createServiceDependency().setService(LogService.class));{code}
>
> *Support for multiple configuration types in callbacks*
> The ConfigurationDependency and Factory components can now support updated
> callbacks with multiple configuration types, for example, the following
> Activator defines a factory component (using the enhanced api) and multiple
> configuration types can now be provided:
> {code:java}
> public class Activator extends DependencyActivatorBase {
> @Override
> public void init(BundleContext context, DependencyManager dm) throws
> Exception {
> Component factoryComponent = createFactoryComponent()
> .setFactoryPid(pid).
> .setConfigType(MyConfig1.class, MyConfig2.class)
> .setImplementation(MyComponent.class);
> dm.add(factoryComponent);
> }
> }
> public class MyComponent {
> void updated(MyConfig1 cnf1, MyConfig2 cnf2) { ... }
> }{code}
> Moreover, you can define a Dictionary parameter as the first argument in the
> updated callback, because sometimes, it's useful to be injected with the raw
> dictionary configuration, as well as with the configuration types. Example:
> {code:java}
> public class MyComponent {
> void updated(Dictionary<String, Object> rawConfig, MyConfig1 cnf1,
> MyConfig2 cnf2) { ... }
> }{code}
> so, the new signatures for the updated callbacks are now the following (for
> both ConfigurationDependency and Factory Component):
> * updated(Dictionary cnf)
> * updated(Component comp, Dictionary cnf)
> * updated(Component comp, Property interfaces ...)
> * updated(Property interfaces ...)
> * updated(Dictionary cnf, Property interfaces ...)
> * updated(Component comp, Dictionary cnf, Property interfaces ...)
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)