felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1731147 [4/7] - in /felix/trunk/dependencymanager: org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/ org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefact...
Date Thu, 18 Feb 2016 21:07:18 GMT
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" =&gt; "a", "arr.1" =&gt; "b", "arr.2" =&gt; "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>
  *



Mime
View raw message