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>
  *


Reply via email to