[ 
https://issues.apache.org/jira/browse/FELIX-5941?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pierre De Rop updated FELIX-5941:
---------------------------------
    Fix Version/s:     (was: org.apache.felix.dependencymanager-r12)
                   org.apache.felix.dependencymanager-r13

> 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-r13
>
>
> 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)

Reply via email to