Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java Thu Feb 18 21:07:16 2016 @@ -1,24 +1,128 @@ package org.apache.felix.dm.lambda; +import java.util.Collection; +import java.util.Dictionary; +import java.util.Map; + import org.apache.felix.dm.ConfigurationDependency; -import org.apache.felix.dm.lambda.callbacks.CbComponentDictionary; +import org.apache.felix.dm.lambda.callbacks.CbConfiguration; +import org.apache.felix.dm.lambda.callbacks.CbConfigurationComponent; import org.apache.felix.dm.lambda.callbacks.CbDictionary; -import org.apache.felix.dm.lambda.callbacks.CbTypeComponentDictionary; -import org.apache.felix.dm.lambda.callbacks.CbTypeDictionary; +import org.apache.felix.dm.lambda.callbacks.CbDictionaryComponent; +import org.apache.felix.dm.lambda.callbacks.InstanceCbConfiguration; +import org.apache.felix.dm.lambda.callbacks.InstanceCbConfigurationComponent; +import org.apache.felix.dm.lambda.callbacks.InstanceCbDictionary; +import org.apache.felix.dm.lambda.callbacks.InstanceCbDictionaryComponent; /** * Builds a Dependency Manager Configuration Dependency. - * By default, the updated callback is "updated", like in original DM API. + * Two families of callbacks are supported: <p> + * + * <ul> + * <li>reflection based callbacks: you specify a callback method name + * <li>method reference callbacks: you specify a java8 method reference + * </ul> + * + * <p> Callbacks may accept a Dictionary, a Component, or a user defined configuration type interface. + * + * If you only specify a pid, by default the callback method name is assumed to be "updated". + * + * <p> Configuration types are a new feature that allows you to specify an interface that is implemented + * by DM and such interface is then injected to your callback instead of the actual Dictionary. + * Using such configuration interface provides a way for creating type-safe configurations from a actual {@link Dictionary} that is + * normally injected by Dependency Manager. + * The callback accepts in argument an interface that you have to provide, and DM will inject a proxy that converts + * method calls from your configuration-type to lookups in the actual map or dictionary. The results of these lookups are then + * converted to the expected return type of the invoked configuration method.<br> + * As proxies are injected, no implementations of the desired configuration-type are necessary! + * </p> + * <p> + * The lookups performed are based on the name of the method called on the configuration type. The method names are + * "mangled" to the following form: <tt>[lower case letter] [any valid character]*</tt>. Method names starting with + * <tt>get</tt> or <tt>is</tt> (JavaBean convention) are stripped from these prefixes. For example: given a dictionary + * with the key <tt>"foo"</tt> can be accessed from a configuration-type using the following method names: + * <tt>foo()</tt>, <tt>getFoo()</tt> and <tt>isFoo()</tt>. + * </p> + * <p> + * The return values supported are: primitive types (or their object wrappers), strings, enums, arrays of + * primitives/strings, {@link Collection} types, {@link Map} types, {@link Class}es and interfaces. When an interface is + * returned, it is treated equally to a configuration type, that is, it is returned as a proxy. + * </p> + * <p> + * Arrays can be represented either as comma-separated values, optionally enclosed in square brackets. For example: + * <tt>[ a, b, c ]</tt> and <tt>a, b,c</tt> are both considered an array of length 3 with the values "a", "b" and "c". + * Alternatively, you can append the array index to the key in the dictionary to obtain the same: a dictionary with + * "arr.0" => "a", "arr.1" => "b", "arr.2" => "c" would result in the same array as the earlier examples. + * </p> + * <p> + * Maps can be represented as single string values similarly as arrays, each value consisting of both the key and value + * separated by a dot. Optionally, the value can be enclosed in curly brackets. Similar to array, you can use the same + * dot notation using the keys. For example, a dictionary with + * + * <pre>{@code "map" => "{key1.value1, key2.value2}"}</pre> + * + * and a dictionary with <p> + * + * <pre>{@code "map.key1" => "value1", "map2.key2" => "value2"}</pre> + * + * result in the same map being returned. + * Instead of a map, you could also define an interface with the methods <tt>getKey1()</tt> and <tt>getKey2</tt> and use + * that interface as return type instead of a {@link Map}. + * </p> + * <p> + * In case a lookup does not yield a value from the underlying map or dictionary, the following rules are applied: + * <ol> + * <li>primitive types yield their default value, as defined by the Java Specification; + * <li>string, {@link Class}es and enum values yield <code>null</code>; + * <li>for arrays, collections and maps, an empty array/collection/map is returned; + * <li>for other interface types that are treated as configuration type a null-object is returned. + * </ol> + * </p> + * + * <b> Sample codes: </b> + * + * <p> Code example with a component that defines a Configuration Dependency using a specific callback method reference, + * and the method accepts in argument a configuration type (the pid is assumed to be the fqdn of the configuration type): + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { + * component(comp -> comp + * .impl(ServiceImpl.class) + * .withConf(conf -> conf.update(MyConfig.class, ServiceImpl::modified))); + * } + * } + * }</pre> * - * <p> Code example with a component that defines a Configuration Dependency. the ServiceImpl modified method - * callback is declared using a method reference (see the "cb(ServiceImpl::modified)" code): + * <p> Code example with a component that defines a Configuration Dependency using a specific callback method reference + * which accepts a Dictionary in argument: * * <pre> {@code * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * component(comp -> comp * .impl(ServiceImpl.class) - * .withConf(conf -> conf.pid(ServiceConsumer.class).cb(ServiceImpl::modified))); + * .withConf(conf -> conf.pid("my.pid").update(ServiceImpl::modified))); + * } + * } + * }</pre> + * + * <p> Code example which defines a configuration dependency injected in the "ServiceImpl.updated(Dictionary)" callback: + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { + * component(comp -> comp.impl(ServiceImpl.class).withConf("my.pid")); + * } + * } + * }</pre> + * + * <p> Code example with a component that defines a Configuration Dependency using a specific callback method name: + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { + * component(comp -> comp.impl(ServiceImpl.class).withConf(conf -> conf.pid("my.pid").update("modified"))); * } * } * }</pre> @@ -29,21 +133,13 @@ public interface ConfigurationDependency /** * Sets the pid for this configuration dependency. * - * @param pid the configuration dependendency pid. + * @param pid the configuration dependency pid. * @return this builder */ ConfigurationDependencyBuilder pid(String pid); /** - * Sets the class which fqdn represents the pid for this configuration dependency. Usually, this class can optionally be annotated with metatypes bnd annotations. - * - * @param pidClass the class which fqdn represents the pid for this configuration dependency. - * @return this builder - */ - ConfigurationDependencyBuilder pid(Class<?> pidClass); - - /** - * Sets propagation of the configuration properties to the service properties (false by default). + * Sets propagation of the configuration to the service properties (false by default). * All public configuration properties (not starting with a dot) will be propagated to the component service properties. * * @return this builder @@ -57,73 +153,146 @@ public interface ConfigurationDependency * @return this builder */ ConfigurationDependencyBuilder propagate(boolean propagate); - + /** - * Configures whether or not the component instance should be instantiated at the time the updated callback is invoked. - * By default, when the callback is applied on an external object instance, the component is not instantiated, but in this case - * you can force the creation of the component instances by calling this method. - * - * @param needsInstance true if the component instance should be instantiated at the time the updated callback is invoked on an external object instance. + * Sets a callback method to call on the component implementation class(es) when the configuration is updated. When the configuration is lost, the callback is invoked + * with a null dictionary. The following callback signatures are supported and searched in the following order: + * <ol> + * <li>method(Dictionary)</li> + * <li>method(Component, Dictionary)</li> + * </ol> + * + * @param updateMethod the name of the callback * @return this builder */ - ConfigurationDependencyBuilder needsInstance(boolean needsInstance); + ConfigurationDependencyBuilder update(String updateMethod); /** - * Sets a <code>callback</code> to call on the component instance(s) when the configuration is updated. + * Sets a callback method to call on the component implementation class(es) when the configuration is updated. The callback is invoked with a configuration type + * argument (null if the configuration is lost). * + * @param configType the type of a configuration that is passed as argument to the callback * @param updateMethod the callback to call on the component instance(s) when the configuration is updated. * @return this builder */ - ConfigurationDependencyBuilder cb(String updateMethod); + ConfigurationDependencyBuilder update(Class<?> configType, String updateMethod); /** - * Sets a <code>callback instance</code> to call on a given object instance when the configuration is updated. - * When the updated method is invoked, the Component implementation has not yet been instantiated, unless you have called - * the @link {@link #needsInstance(boolean)} method with "true". + * Sets a callback method to call on a given Object instance when the configuration is updated. + * When the updated method is invoked, the Component implementation is not yet instantiated. This method + * can be typically used by a Factory object which needs the configuration before it can create the actual + * component implementation instance(s). + * + * When the configuration is lost, the callback is invoked with a null dictionary, and the following signatures are supported: + * <ol> + * <li>method(Dictionary)</li> + * <li>method(Component, Dictionary)</li> + * </ol> + * + * @param callbackInstance the object instance on which the updatedMethod is invoked + * @param updateMethod the callback to call on the callbackInstance when the configuration is updated. + * @return this builder + */ + ConfigurationDependencyBuilder update(Object callbackInstance, String updateMethod); + + /** + * Sets a callback method to call on a given Object instance when the configuration is updated. + * When the updated method is invoked, the Component implementation is not yet instantiated. This method + * can be typically used by a Factory object which needs the configuration before it can create the actual + * component implementation instance(s). + * The callback is invoked with a configuration type argument (null of the configuration is lost). * + * @param configType the type of a configuration that is passed as argument to the callback * @param callbackInstance the object instance on which the updatedMethod is invoked * @param updateMethod the callback to call on the callbackInstance when the configuration is updated. * @return this builder */ - ConfigurationDependencyBuilder cbi(Object callbackInstance, String updateMethod); + ConfigurationDependencyBuilder update(Class<?> configType, Object callbackInstance, String updateMethod); + + /** + * Sets a reference to a "callback(Dictionary)" method from one of the component implementation classes. + * The method is invoked with a Dictionary argument (which is null if the configuration is lost). + * + * @param <T> The type of the target component implementation class on which the method is invoked + * @param callback a reference to a method of one of the component implementation classes. + * @return this builder + */ + <T> ConfigurationDependencyBuilder update(CbDictionary<T> callback); + + /** + * Sets a reference to a "callback(Dictionary, Component)" method from one of the component implementation classes. + * The method is invoked with Dictionary/Component arguments. When the configuration is lost, the Dictionary argument + * is null. + * + * @param <T> The type of the target component implementation class on which the method is invoked + * @param callback a reference to a method callback defined in one of the the component implementation classes. + * @return this builder + */ + <T> ConfigurationDependencyBuilder update(CbDictionaryComponent<T> callback); /** - * Sets a <code>callback</code> method reference used to invoke an update method. The method reference must point to a method from one of the component - * implementation classes, and is invoked when the configuration is updated. + * Sets a reference to a "callback(Configuration)" method from one of the component implementation classes. + * The method is invoked with a configuration type argument (null if the configuration is lost). * - * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param <T> The type of the target component implementation class on which the method is invoked + * @param <U> the type of the configuration interface accepted by the callback method. + * @param configType the type of a configuration that is passed as argument to the callback * @param callback the callback method reference which must point to a method from one of the component implementation classes. The method - * takes as argument a Dictionary. + * takes as argument an interface which will be implemented by a dynamic proxy that wraps the actual configuration properties. * @return this builder */ - <T> ConfigurationDependencyBuilder cb(CbTypeDictionary<T> callback); + <T, U> ConfigurationDependencyBuilder update(Class<U> configType, CbConfiguration<T, U> callback); /** - * Sets the <code>callback</code> method reference used to invoke an update method. The method reference must point to a method from one of the - * component implementation classes, and is invoked when the configuration is updated. + * Sets a reference to a "callback(configType, Component)" method from one of the component implementation classes. + * The method is invoked with two args: configuration type, Component. The configuration type argument is null if the configuration is lost. * - * @param <T> the type of the component implementation class on which the callback is invoked on. - * @param callback the callback method reference used to invoke an update method on the component instance(s) when the configuration is updated. - * The method takes as argument a Component and a Dictionary. + * @param <T> The type of the target component implementation class on which the method is invoked + * @param <U> the type of the configuration interface accepted by the callback method. + * @param configType the type of a configuration that is passed as argument to the callback + * @param callback the reference to a method from one of the component implementation classes. The method + * takes as argument an interface which will be implemented by a dynamic proxy that wraps the actual configuration properties. It also + * takes as the second argument a Component object. * @return this builder */ - <T> ConfigurationDependencyBuilder cb(CbTypeComponentDictionary<T> callback); - + <T, U> ConfigurationDependencyBuilder update(Class<U> configType, CbConfigurationComponent<T, U> callback); + /** - * Sets a <code>callback instance</code> method reference used to invoke the update method. The method reference must point to an Object instance - * method which takes as argument a Dictionary. + * Sets a reference to a "callback(Dictionary)" method from an Object instance. * - * @param updated a method reference that points to an Object instance method which takes as argument a Dictionary. + * @param callback a reference to an Object instance which takes as argument a Dictionary (null if the configuration is lost). * @return this builder */ - ConfigurationDependencyBuilder cbi(CbDictionary updated); - + ConfigurationDependencyBuilder update(InstanceCbDictionary callback); + /** - * Sets a <code>callback instance</code> method reference used to invoke the update method. The method reference must point to an Object instance method - * which takes as argument a Component and a Dictionary. + * Sets a reference to a "callback(Dictionary, Component)" method from an Object instance. The method accepts + * a Dictionary and a Component object. The passed Dictionary is null in case the configuration is lost. * - * @param updated a method reference that points to an Object instance method which takes as argument a Component and a Dictionary. + * @param callback a reference to method from an Object instance which takes as argument a Dictionary and a Component + * @return this builder + */ + ConfigurationDependencyBuilder update(InstanceCbDictionaryComponent callback); + + /** + * Sets a reference to a "callback(ConfigType)" method from an Object instance. The configuration type argument is null if the configuration is lost. + * + * @param <T> the type of the configuration interface accepted by the callback method. + * @param configType the class of the configuration that is passed as argument to the callback + * @param updated a reference to an Object instance which takes as argument the given configuration type * @return this builder */ - ConfigurationDependencyBuilder cbi(CbComponentDictionary updated); + <T> ConfigurationDependencyBuilder update(Class<T> configType, InstanceCbConfiguration<T> updated); + + /** + * Sets a reference to a "callback(Configuration, Component)" method from an Object instance. The method accepts + * a configuration type and a Component object. The configuration type argument is null if the configuration is lost. + * + * @param <T> the type of the configuration interface accepted by the callback method. + * @param configType the class of the configuration that is passed as argument to the callback + * @param updated a reference to an Object instance which takes as argument a the given configuration type, and a Component object. + * @return this builder + */ + <T> ConfigurationDependencyBuilder update(Class<T> configType, InstanceCbConfigurationComponent<T> updated); } +
Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyManagerActivator.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyManagerActivator.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyManagerActivator.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyManagerActivator.java Thu Feb 18 21:07:16 2016 @@ -27,11 +27,11 @@ import org.osgi.framework.BundleContext; * import org.apache.felix.dm.lambda.DependencyManagerActivator; * * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * component(comp -> comp * .provides(Service.class, property -> "value") * .impl(ServiceImpl.class) - * .withSrv(LogService.class, ConfigurationAdmni.class) // both services are required and injected in class fields with compatible types. + * .withSvc(LogService.class, ConfigurationAdmni.class) // both services are required and injected in class fields with compatible types. * } * } * }</pre> @@ -42,12 +42,12 @@ import org.osgi.framework.BundleContext; * import org.apache.felix.dm.lambda.DependencyManagerActivator; * * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * component(comp -> comp * .provides(Service.class, property -> "value") * .impl(ServiceImpl.class) - * .withSrv(LogService.class, log -> log.cb("setLog")) - * .withSrv(ConfigurationAdmni.class, cm -> cm.cb("setConfigAdmin"))) + * .withSvc(LogService.class, svc -> svc.add("setLog")) + * .withSvc(ConfigurationAdmni.class, svc -> svc.add("setConfigAdmin"))) * } * } * }</pre> @@ -58,12 +58,12 @@ import org.osgi.framework.BundleContext; * import org.apache.felix.dm.lambda.DependencyManagerActivator; * * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * component(comp -> comp * .provides(Service.class, property -> "value") * .impl(ServiceImpl.class) - * .withSrv(LogService.class, log -> log.cb(ServiceImpl::setLog)) - * .withSrv(ConfigurationAdmni.class, cm -> cm.cb(ServiceImpl::setConfigAdmin))) + * .withSvc(LogService.class, svc -> svc.add(ServiceImpl::setLog)) + * .withSvc(ConfigurationAdmni.class, svc -> svc.add(ServiceImpl::setConfigAdmin))) * } * } * }</pre> @@ -80,7 +80,7 @@ public abstract class DependencyManagerA @Override public void start(BundleContext context) throws Exception { m_manager = new DependencyManager(context); - activate(); + init(context, m_manager); } /** @@ -88,21 +88,22 @@ public abstract class DependencyManagerA */ @Override public void stop(BundleContext context) throws Exception { - deactivate(); + destroy(); } /** * Sub classes must override this method in order to build some DM components. - * + * @param ctx the context associated to the bundle + * @param dm the DependencyManager assocaited to this activator * @throws Exception if the activation fails */ - protected abstract void activate() throws Exception; + protected abstract void init(BundleContext ctx, DependencyManager dm) throws Exception; /** * Sub classes may override this method that is called when the Activator is stopped. * @throws Exception if the deactivation fails */ - protected void deactivate() throws Exception { + protected void destroy() throws Exception { } /** Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FactoryPidAdapterBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FactoryPidAdapterBuilder.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FactoryPidAdapterBuilder.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FactoryPidAdapterBuilder.java Thu Feb 18 21:07:16 2016 @@ -1,26 +1,56 @@ package org.apache.felix.dm.lambda; -import org.apache.felix.dm.lambda.callbacks.CbComponentDictionary; +import org.apache.felix.dm.lambda.callbacks.CbConfiguration; +import org.apache.felix.dm.lambda.callbacks.CbConfigurationComponent; import org.apache.felix.dm.lambda.callbacks.CbDictionary; -import org.apache.felix.dm.lambda.callbacks.CbTypeComponentDictionary; -import org.apache.felix.dm.lambda.callbacks.CbTypeDictionary; +import org.apache.felix.dm.lambda.callbacks.CbDictionaryComponent; +import org.apache.felix.dm.lambda.callbacks.InstanceCbConfiguration; +import org.apache.felix.dm.lambda.callbacks.InstanceCbConfigurationComponent; +import org.apache.felix.dm.lambda.callbacks.InstanceCbDictionary; +import org.apache.felix.dm.lambda.callbacks.InstanceCbDictionaryComponent; /** * Builds a Dependency Manager Factory Configuration Adapter Component. For each new Config Admin factory configuration matching the factoryPid, * an adapter will be created based on the adapter implementation class. The adapter will be registered with the specified interface, * and with the specified adapter service properties. Depending on the propagate parameter, every public factory configuration properties - * (which don't start with ".") will be propagated along with the adapter service properties. + * (which don't start with ".") will be propagated along with the adapter service properties. + * + * This builded supports type safe configuration types. For a given factory configuration, you can specify an interface of your choice, + * and DM will implement it using a dynamic proxy that converts interface methods to lookups in the actual factory configuration dictionary. * * <p> Example that defines a factory configuration adapter service for the "foo.bar" factory pid: * * <pre> {@code * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * factoryPidAdapter(adapter -> adapter * .impl(DictionaryImpl.class) - * .factoryPid("foo.bar").cb(ServiceImpl::updated) + * .factoryPid("foo.bar") + * .update(ServiceImpl::updated) * .propagate() - * .withSrv(LogService.class, log -> log.optional())); + * .withSvc(LogService.class, log -> log.optional())); + * } + * } + * }</pre> + * + * <p> Example that defines a factory configuration adapter using a user defined configuration type + * (the pid is by default assumed to match the fqdn of the configuration type): + * + * <pre> {@code + * + * public interface DictionaryConfiguration { + * public String getLanguage(); + * public List<String> getWords(); + * } + * + * public class Activator extends DependencyManagerActivator { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { + * factoryPidAdapter(adapter -> adapter + * .impl(DictionaryImpl.class) + * .factoryPid("foo.bar") + * .update(DictionaryConfiguration.class, ServiceImpl::updated) + * .propagate() + * .withSvc(LogService.class, log -> log.optional())); * } * } * }</pre> @@ -32,29 +62,25 @@ public interface FactoryPidAdapterBuilde * @return this builder */ FactoryPidAdapterBuilder factoryPid(String pid); - - /** - * Specifies a class name which fqdn represents the factory pid. Usually, this class can optionally be annotated with metatypes bnd annotations. - * @param pidClass the class that acts as the factory pid - * @return this builder - */ - FactoryPidAdapterBuilder factoryPid(Class<?> pidClass); - + /** * Specifies if the public properties (not starting with a dot) should be propagated in the adapter service properties (false by default). + * * @return this builder. */ FactoryPidAdapterBuilder propagate(); /** * Specifies if the public properties (not starting with a dot) should be propagated in the adapter service properties (false by default). + * * @param propagate true if the public properties should be propagated in the adapter service properties (false by default). * @return this builder. */ FactoryPidAdapterBuilder propagate(boolean propagate); /** - * Specifies a callback method that will be called on the component instances when the configuration is injected + * Specifies a callback method that will be called on the component instances when the configuration is injected. + * * @param updateMethod the method to call on the component instances when the configuration is available ("updated" by default). * The following method signatures are supported: * @@ -65,10 +91,21 @@ public interface FactoryPidAdapterBuilde * * @return this builder */ - FactoryPidAdapterBuilder cb(String updateMethod); + FactoryPidAdapterBuilder update(String updateMethod); /** - * Specifies a callback instance method that will be called on a given object instance when the configuration is injected + * Sets a callback method to call on the component implementation class(es) when the configuration is updated. + * The callback is invoked with a configuration type argument. + * + * @param configType the type of a configuration that is passed as argument to the callback + * @param updateMethod the callback to call on the component instance(s) when the configuration is updated. + * @return this builder + */ + FactoryPidAdapterBuilder update(Class<?> configType, String updateMethod); + + /** + * Specifies a callback instance method that will be called on a given object instance when the configuration is injected. + * * @param updateMethod the method to call on the given object instance when the configuration is available ("updated" by default). * The following method signatures are supported: * @@ -80,41 +117,101 @@ public interface FactoryPidAdapterBuilde * @param callbackInstance the Object instance on which the updated callback will be invoked. * @return this builder */ - FactoryPidAdapterBuilder cb(Object callbackInstance, String updateMethod); + FactoryPidAdapterBuilder update(Object callbackInstance, String updateMethod); /** - * Specifies a callback method reference that will be called on one of the component classes when the configuration is injected. + * Specifies a callback instance method that will be called on a given object instance when the configuration is injected. + * The callback is invoked with a configuration type argument. * - * @param <U> the type of the component implementation class on which the callback is invoked on. + * @param configType the type of a configuration that is passed as argument to the callback + * @param callbackInstance the Object instance on which the updated callback will be invoked. + * @param updateMethod the method to call on the given object instance when the configuration is available. The callback is invoked + * with a configuration type argument (matching the configType you have specified. + * @return this builder + */ + FactoryPidAdapterBuilder update(Class<?> configType, Object callbackInstance, String updateMethod); + + /** + * Specifies a method reference that will be called on one of the component classes when the configuration is injected. + * The callback is invoked with a Dictionary argument. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param callback the method to call on one of the component classes when the configuration is available. + * @return this builder + */ + <T> FactoryPidAdapterBuilder update(CbDictionary<T> callback); + + /** + * Specifies a method reference that will be called on one of the component classes when the configuration is injected. + * The callback is invoked with a configuration type argument. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param <U> the configuration type accepted by the callback method. + * @param configType the type of a configuration that is passed as argument to the callback * @param callback the method to call on one of the component classes when the configuration is available. * @return this builder */ - <U> FactoryPidAdapterBuilder cb(CbTypeDictionary<U> callback); + <T, U> FactoryPidAdapterBuilder update(Class<U> configType, CbConfiguration<T, U> callback); /** - * Specifies a callback method reference that will be called on one of the component classes when the configuration is injected + * Specifies a method reference that will be called on one of the component classes when the configuration is injected * - * @param <U> the type of the component implementation class on which the callback is invoked on. - * @param callback the reference to a method on one of the component classes. The method may takes as parameter a Component and a Dictionary. + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param callback the reference to a method on one of the component classes. The method may takes as parameter a Dictionary and a Component. * @return this builder */ - <U> FactoryPidAdapterBuilder cb(CbTypeComponentDictionary<U> callback); + <T> FactoryPidAdapterBuilder update(CbDictionaryComponent<T> callback); /** - * Specifies a callback instance method reference that will be called on a given object instance when the configuration is injected + * Specifies a method reference that will be called on one of the component classes when the configuration is injected. + * The callback is invoked with the following arguments: a configuration type, and a Component object. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param <U> the configuration type accepted by the callback method. + * @param configType the type of a configuration that is passed as argument to the callback + * @param callback the reference to a method on one of the component classes. The method may takes as parameter a configuration type and a Component. + * @return this builder + */ + <T, U> FactoryPidAdapterBuilder update(Class<U> configType, CbConfigurationComponent<T, U> callback); + + /** + * Specifies a method reference that will be called on a given object instance when the configuration is injected * * @param callback the method to call on a given object instance when the configuration is available. The callback takes as argument a * a Dictionary parameter. * @return this builder */ - FactoryPidAdapterBuilder cbi(CbDictionary callback); + FactoryPidAdapterBuilder update(InstanceCbDictionary callback); + + /** + * Specifies a method reference that will be called on a given object instance when the configuration is injected. + * The callback is invoked with a type-safe configuration type argument. + * + * @param <T> the configuration type accepted by the callback method. + * @param configType the type of a configuration that is passed as argument to the callback + * @param callback the method to call on a given object instance when the configuration is available. The callback takes as argument a + * a configuration type parameter. + * @return this builder + */ + <T> FactoryPidAdapterBuilder update(Class<T> configType, InstanceCbConfiguration<T> callback); + + /** + * Specifies a method reference that will be called on a given object instance when the configuration is injected. + * + * @param callback the method to call on a given object instance when the configuration is available. The callback takes as argument a + * Dictionary, and a Component parameter. + * @return this builder + */ + FactoryPidAdapterBuilder update(InstanceCbDictionaryComponent callback); /** - * Specifies a callback instance method reference that will be called on a given object instance when the configuration is injected. + * Specifies a method reference that will be called on a given object instance when the configuration is injected. * + * @param <T> the configuration type accepted by the callback method. + * @param configType the type of a configuration that is passed as argument to the callback * @param callback the method to call on a given object instance when the configuration is available. The callback takes as argument a - * Dictionary parameter. + * configuration type, and a Component parameter. * @return this builder */ - FactoryPidAdapterBuilder cbi(CbComponentDictionary callback); + <T> FactoryPidAdapterBuilder update(Class<T> configType, InstanceCbConfigurationComponent<T> callback); } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FluentProperty.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FluentProperty.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FluentProperty.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FluentProperty.java Thu Feb 18 21:07:16 2016 @@ -9,7 +9,7 @@ import org.apache.felix.dm.lambda.callba * * <pre>{@code * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * component(comp -> comp.impl(MyComponentImpl.class).provides(MyService.class, foo->"bar", foo2 -> 123)); * } * } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FutureDependencyBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FutureDependencyBuilder.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FutureDependencyBuilder.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/FutureDependencyBuilder.java Thu Feb 18 21:07:16 2016 @@ -4,7 +4,7 @@ import java.util.concurrent.Executor; import org.apache.felix.dm.Dependency; import org.apache.felix.dm.lambda.callbacks.CbFuture; -import org.apache.felix.dm.lambda.callbacks.CbTypeFuture; +import org.apache.felix.dm.lambda.callbacks.InstanceCbFuture; /** * Defines a builder for a CompletableFuture dependency. @@ -22,7 +22,7 @@ import org.apache.felix.dm.lambda.callba * <pre>{@code * * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * String url = "http://felix.apache.org/"; * CompletableFuture<String> page = CompletableFuture.supplyAsync(() -> downloadSite(url)); * @@ -32,7 +32,7 @@ import org.apache.felix.dm.lambda.callba * component(comp -> comp * .impl(MyComponent.class) * .withService(LogService.class) - * .withFuture(page, result -> result.cb(MyComponent::setPage))); + * .withFuture(page, result -> result.complete(MyComponent::setPage))); * } * } * @@ -58,7 +58,15 @@ public interface FutureDependencyBuilder * @param callback the callback method name to invoke on the component instances, once the CompletableFuture on which we depend has completed. * @return this dependency. */ - FutureDependencyBuilder<F> cb(String callback); + FutureDependencyBuilder<F> complete(String callback); + + /** + * Sets the callback instance method name to invoke on a given Object instance, once the CompletableFuture has completed. + * @param callbackInstance the object instance on which the callback must be invoked + * @param callback the callback method name to invoke on Object instance, once the CompletableFuture has completed. + * @return this dependency. + */ + FutureDependencyBuilder<F> complete(Object callbackInstance, String callback); /** * Sets the function to invoke when the future task has completed. The function is from one of the Component implementation classes, and it accepts the @@ -68,7 +76,7 @@ public interface FutureDependencyBuilder * @param callback the function to perform when the future task as completed. * @return this dependency */ - <T> FutureDependencyBuilder<F> cb(CbTypeFuture<T, ? super F> callback); + <T> FutureDependencyBuilder<F> complete(CbFuture<T, ? super F> callback); /** * Sets the function to invoke asynchronously when the future task has completed. The function is from one of the Component implementation classes, @@ -79,7 +87,7 @@ public interface FutureDependencyBuilder * @param async true if the callback should be invoked asynchronously using the default jdk execution facility, false if not. * @return this dependency */ - <T> FutureDependencyBuilder<F> cb(CbTypeFuture<T, ? super F> callback, boolean async); + <T> FutureDependencyBuilder<F> complete(CbFuture<T, ? super F> callback, boolean async); /** * Sets the function to invoke asynchronously when the future task has completed. The function is from one of the Component implementation classes, @@ -90,23 +98,15 @@ public interface FutureDependencyBuilder * @param executor the executor used to schedule the callback. * @return this dependency */ - <T> FutureDependencyBuilder<F> cb(CbTypeFuture<T, ? super F> callback, Executor executor); + <T> FutureDependencyBuilder<F> complete(CbFuture<T, ? super F> callback, Executor executor); /** - * Sets the callback instance method name to invoke on a given Object instance, once the CompletableFuture has completed. - * @param callbackInstance the object instance on which the callback must be invoked - * @param callback the callback method name to invoke on Object instance, once the CompletableFuture has completed. - * @return this dependency. - */ - FutureDependencyBuilder<F> cbi(Object callbackInstance, String callback); - - /** * Sets the callback instance to invoke when the future task has completed. The callback is a Consumer instance which accepts the * result of the completed future. * @param callback a Consumer instance which accepts the result of the completed future. * @return this dependency */ - FutureDependencyBuilder<F> cbi(CbFuture<? super F> callback); + FutureDependencyBuilder<F> complete(InstanceCbFuture<? super F> callback); /** * Sets the callback instance to invoke when the future task has completed. The callback is a Consumer instance which accepts the @@ -116,7 +116,7 @@ public interface FutureDependencyBuilder * @param async true if the callback should be invoked asynchronously using the default jdk execution facility, false if not. * @return this dependency */ - FutureDependencyBuilder<F> cbi(CbFuture<? super F> callback, boolean async); + FutureDependencyBuilder<F> complete(InstanceCbFuture<? super F> callback, boolean async); /** * Sets the callback instance to invoke when the future task has completed. The callback is a Consumer instance which accepts the @@ -125,5 +125,5 @@ public interface FutureDependencyBuilder * @param executor the executor to use for asynchronous execution of the callback. * @return this dependency */ - FutureDependencyBuilder<F> cbi(CbFuture<? super F> callback, Executor executor); + FutureDependencyBuilder<F> complete(InstanceCbFuture<? super F> callback, Executor executor); } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAdapterBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAdapterBuilder.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAdapterBuilder.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAdapterBuilder.java Thu Feb 18 21:07:16 2016 @@ -10,7 +10,7 @@ package org.apache.felix.dm.lambda; * * <pre> {@code * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * adapter(Device.class, adapt -> adapt.impl(DeviceServlet.class).provides(HttpServlet.class).properties(alias -> "/device"); * } * }}</pre> Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAspectBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAspectBuilder.java?rev=1731147&r1=1731146&r2=1731147&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAspectBuilder.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceAspectBuilder.java Thu Feb 18 21:07:16 2016 @@ -13,8 +13,8 @@ package org.apache.felix.dm.lambda; * * <pre>{@code * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { - * aspect(LogService.class, asp -> asp.impl(SpellCheckLogAspect.class).rank(10).withSrv(Dictionary.class)); + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { + * aspect(LogService.class, asp -> asp.impl(SpellCheckLogAspect.class).rank(10).withSvc(Dictionary.class)); * } * }} </pre> * @@ -22,10 +22,11 @@ package org.apache.felix.dm.lambda; * * <pre>{@code * public class Activator extends DependencyManagerActivator { - * public void activate() throws Exception { - * aspect(LogService.class, asp -> asp.impl(SpellCheckLogAspect.class).rank(10) - * .cb(SpellCheckLogAspect::setLogService) - * .withSrv(Dictionary.class, dict -> dict.cb(SpellCheckLogAspect::setDictionary))); + * public void init(BundleContext ctx, DependencyManager dm) throws Exception { + * aspect(LogService.class, asp -> asp + * .impl(SpellCheckLogAspect.class).rank(10) + * .add(SpellCheckLogAspect::setLogService) + * .withSvc(Dictionary.class, svc -> svc.add(SpellCheckLogAspect::setDictionary))); * } * }} </pre> *
