Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/BundleDependencyBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/BundleDependencyBuilderImpl.java?rev=1724333&r1=1724332&r2=1724333&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/BundleDependencyBuilderImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/BundleDependencyBuilderImpl.java
 Tue Jan 12 22:45:36 2016
@@ -13,11 +13,14 @@ import org.apache.felix.dm.BundleDepende
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.builder.lambda.BundleDependencyBuilder;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer2;
+import org.apache.felix.dm.builder.lambda.Functions.CbBundle;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentBundle;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeBundle;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentBundle;
 import org.osgi.framework.Bundle;
 
-public class BundleDependencyBuilderImpl implements BundleDependencyBuilder {
+@SuppressWarnings("unchecked")
+public class BundleDependencyBuilderImpl<T> implements 
BundleDependencyBuilder<T> {
        private String m_added;
        private String m_changed;
        private String m_removed;
@@ -33,7 +36,7 @@ public class BundleDependencyBuilderImpl
        private String m_propagateMethod;
        private Supplier<Dictionary<?, ?>> m_propagateSupplier;
        private final Component m_component;
-       
+    
        /**
         * This interface (lambda) is called when we want to invoke a method 
reference. the lambda is called with all necessary dependency 
         * informations.
@@ -67,192 +70,229 @@ public class BundleDependencyBuilderImpl
     }
 
     @Override
-       public BundleDependencyBuilder onAdd(String callback) {
-       return callbacks(callback, null, null);
-       }
+    public BundleDependencyBuilder<T> autoConfig(boolean autoConfig) {
+        m_autoConfig = autoConfig;
+        m_autoConfigInvoked = true;
+        return this;
+    }
 
     @Override
-       public BundleDependencyBuilder onChange(String callback) {
-       return callbacks(null, callback, null);
-       }
+    public BundleDependencyBuilder<T> autoConfig() {
+        autoConfig(true);
+        return this;
+    }
 
     @Override
-       public BundleDependencyBuilder onRemove(String callback) {
-       return callbacks(null, null, callback);
-       }
+    public BundleDependencyBuilder<T> required(boolean required) {
+        m_required = required;
+        return this;
+    }
 
     @Override
-       public BundleDependencyBuilder callbacks(String added, String removed) {
-       return callbacks(added, null, removed);
-       }
+    public BundleDependencyBuilder<T> required() {
+        required(true);
+        return this;
+    }
 
     @Override
-       public BundleDependencyBuilder callbacks(String added, String changed, 
String removed) {
-       requiresNoMethodRefs();
-       m_added = added != null ? added : m_added;
-               m_changed = changed != null ? changed : m_changed;
-               m_removed = removed != null ? removed : m_removed;
-               if (! m_autoConfigInvoked) m_autoConfig = false;
-               return this;
-       }
+    public BundleDependencyBuilder<T> bundle(Bundle bundle) {
+        m_bundle = bundle;
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder callbacks(Object instance, String added, 
String changed, String removed) {
-               callbacks(added, changed, removed);
-               m_instance = instance;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> filter(String filter) throws 
IllegalArgumentException {
+        m_filter = filter;
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder onAdd(Consumer<Bundle> add) {
-       return setCallbackRef("add", (instance, component, bundle) -> 
add.accept(bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> mask(int mask) {
+        m_stateMask = mask;
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder onAdd(Consumer2<Component, Bundle> add) {
-       return setCallbackRef("add", (instance, component, bundle) -> 
add.accept(component, bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> propagate(boolean propagate) {
+        m_propagate = propagate;
+        return this;
+    }
 
-       @SuppressWarnings("unchecked")
-       @Override
-       public <I> BundleDependencyBuilder onAdd(InstanceBundle<I> add) {
-       String type = Helpers.getLambdaGenericType(add);
-       return setComponentInstanceCallbackRef("add", type,   
-                       (inst, component, bundle) -> add.call((I) inst, 
bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> propagate() {
+        propagate(true);
+        return this;
+    }
 
-       @SuppressWarnings("unchecked")
-       @Override
-       public <I> BundleDependencyBuilder onAdd(InstanceComponentBundle<I> 
add) {
-       String type = Helpers.getLambdaGenericType(add);
-       return setComponentInstanceCallbackRef("add", type,   
-                       (inst, component, bundle) -> add.call((I) inst, 
component, bundle));             
-       }
-       
-       @Override
-       public BundleDependencyBuilder onChange(Consumer<Bundle> add) {
-       return setCallbackRef("change", (instance, component, bundle) -> 
add.accept(bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> propagate(Object instance, String 
method) {
+        if (m_propagateSupplier != null || m_propagate) throw new 
IllegalStateException("Propagate callback already set.");
+        Objects.nonNull(method);
+        Objects.nonNull(instance);
+        m_propagateInstance = instance;
+        m_propagateMethod = method;
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder onChange(Consumer2<Component, Bundle> 
change) {
-       return setCallbackRef("change", (instance, component, bundle) -> 
change.accept(component, bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> propagate(Supplier<Dictionary<?, ?>> 
instance) {
+        if (m_propagateInstance != null || m_propagate) throw new 
IllegalStateException("Propagate callback already set.");
+        m_propagateSupplier = instance;
+        return this;
+    }
+    
+    @Override
+    public BundleDependencyBuilder<T> cb(String add) {
+        cb(add, null, null);
+        return this;
+    }
+    
+    @Override
+    public BundleDependencyBuilder<T> cb(String add, String remove) {
+        cb(add, null, remove);
+        return this;
+    }
+        
+    public BundleDependencyBuilder cb(String added, String changed, String 
removed) {
+        requiresNoMethodRefs();
+        m_added = added != null ? added : m_added;
+        m_changed = changed != null ? changed : m_changed;
+        m_removed = removed != null ? removed : m_removed;
+        if (! m_autoConfigInvoked) m_autoConfig = false;
+        return this;
+    }
 
-       @SuppressWarnings("unchecked")
-       @Override
-       public <I> BundleDependencyBuilder onChange(InstanceBundle<I> change) {
-       String type = Helpers.getLambdaGenericType(change);
-       return setComponentInstanceCallbackRef("change", type,   
-                       (inst, component, bundle) -> change.call((I) inst, 
bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> cbInst(Object instance) {
+        m_instance = instance;
+        return this;
+    }    
 
-       @SuppressWarnings("unchecked")
-       @Override
-       public <I> BundleDependencyBuilder onChange(InstanceComponentBundle<I> 
change) {
-       String type = Helpers.getLambdaGenericType(change);
-       return setComponentInstanceCallbackRef("change", type,   
-                       (inst, component, bundle) -> change.call((I) inst, 
component, bundle));             
-       }
-       
-       @Override
-       public BundleDependencyBuilder onRemove(Consumer<Bundle> remove) {
-       return setCallbackRef("remove", (instance, component, bundle) -> 
remove.accept(bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbTypeBundle<T> add) {      
+        return cb(add, null, null);
+    }
 
-       @Override
-       public BundleDependencyBuilder onRemove(Consumer2<Component, Bundle> 
remove) {
-       return setCallbackRef("remove", (instance, component, bundle) -> 
remove.accept(component, bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbTypeBundle<T> add, CbTypeBundle<T> 
remove) {    
+        return cb(add, null, remove);
+    }
 
-       @SuppressWarnings("unchecked")
-       @Override
-       public <I> BundleDependencyBuilder onRemove(InstanceBundle<I> remove) {
-       String type = Helpers.getLambdaGenericType(remove);
-       return setComponentInstanceCallbackRef("remove", type,   
-                       (inst, component, bundle) -> remove.call((I) inst, 
bundle));             
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbTypeBundle<T> add, CbTypeBundle<T> 
change, CbTypeBundle<T> remove) {    
+        if (add != null) {
+            setComponentCallbackRef("add",
+                (inst, component, bundle) -> add.accept ((T) inst, bundle));
+        }
+        if (change != null) {
+            setComponentCallbackRef("change",
+                (inst, component, bundle) -> change.accept ((T) inst, bundle));
+        }
+        if (remove != null) {
+            setComponentCallbackRef("remove",
+                (inst, component, bundle) -> remove.accept ((T) inst, bundle));
+        }
+        return this;
+    }
 
-       @SuppressWarnings("unchecked")
-       @Override
-       public <I> BundleDependencyBuilder onRemove(InstanceComponentBundle<I> 
remove) {
-       String type = Helpers.getLambdaGenericType(remove);
-       return setComponentInstanceCallbackRef("remove", type,   
-                       (inst, component, bundle) -> remove.call((I) inst, 
component, bundle));             
-       }
-       
-       @Override
-       public BundleDependencyBuilder autoConfig(boolean autoConfig) {
-               m_autoConfig = autoConfig;
-        m_autoConfigInvoked = true;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbTypeComponentBundle<T> add) {
+        return cb(add, null, null);
+    }
+    
+    @Override
+    public BundleDependencyBuilder<T> cb(CbTypeComponentBundle<T> add, 
CbTypeComponentBundle<T> remove) {
+        return cb(add, null, remove);
+    }
 
-       @Override
-       public BundleDependencyBuilder autoConfig() {
-               autoConfig(true);
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbTypeComponentBundle<T> add, 
CbTypeComponentBundle<T> change, CbTypeComponentBundle<T> remove) {
+        if (add != null) {
+            setComponentCallbackRef("add", (inst, component, bundle) -> 
add.accept ((T) inst, component, bundle));
+        }
+        if (change != null) {
+            setComponentCallbackRef("change", (inst, component, bundle) -> 
change.accept ((T) inst, component, bundle));
+        }
+        if (remove != null) {
+            setComponentCallbackRef("remove", (inst, component, bundle) -> 
remove.accept ((T) inst, component, bundle));
+        }
+        return this;            
+    }
 
-       @Override
-       public BundleDependencyBuilder required(boolean required) {
-               m_required = required;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbBundle add) {
+        return cb (add, null, null);      
+    }
 
-       @Override
-       public BundleDependencyBuilder required() {
-               required(true);
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbBundle add, CbBundle remove) {
+        return cb (add, null, remove);      
+    }
 
-       @Override
-       public BundleDependencyBuilder bundle(Bundle bundle) {
-               m_bundle = bundle;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbBundle add, CbBundle change, 
CbBundle remove) {
+        if (add != null) setCallbackRef("add", (inst, component, bundle) -> 
add.accept(bundle));
+        if (change != null)  setCallbackRef("change", (inst, component, 
bundle) -> change.accept(bundle));
+        if (remove != null) setCallbackRef("remove", (inst, component, bundle) 
-> remove.accept(bundle));
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder filter(String filter) throws 
IllegalArgumentException {
-               m_filter = filter;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbComponentBundle add) {
+        return cb(add, null, null);      
+    }
 
-       @Override
-       public BundleDependencyBuilder mask(int mask) {
-               m_stateMask = mask;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbComponentBundle add, 
CbComponentBundle remove) {
+        return cb(add, null, remove);      
+    }
 
-       @Override
-       public BundleDependencyBuilder propagate(boolean propagate) {
-               m_propagate = propagate;
-               return this;
-       }
+    @Override
+    public BundleDependencyBuilder<T> cb(CbComponentBundle add, 
CbComponentBundle change, CbComponentBundle remove) {
+        if (add != null) setCallbackRef("add", (inst, component, bundle) -> 
add.accept(component, bundle));      
+        if (change != null) setCallbackRef("change", (inst, component, bundle) 
-> change.accept(component, bundle));      
+        if (remove != null) setCallbackRef("remove", (inst, component, bundle) 
-> remove.accept(component, bundle));      
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder propagate() {
-               propagate(true);
-               return this;
-       }
+    @Override
+    public <U> BundleDependencyBuilder<T> compositeCb(CbTypeBundle<U> add) { 
+        return compositeCb(add, null, null);
+    }
 
-       @Override
-       public BundleDependencyBuilder propagate(Object instance, String 
method) {
-               if (m_propagateSupplier != null || m_propagate) throw new 
IllegalStateException("Propagate callback already set.");
-               Objects.nonNull(method);
-               Objects.nonNull(instance);
-               m_propagateInstance = instance;
-               m_propagateMethod = method;
-               return this;
-       }
+    @Override
+    public <U> BundleDependencyBuilder<T> compositeCb(CbTypeBundle<U> add, 
CbTypeBundle<U> remove) {      
+        return compositeCb(add, null, remove);
+    }
+
+    @Override
+    public <U> BundleDependencyBuilder<T> compositeCb(CbTypeBundle<U> add, 
CbTypeBundle<U> change, CbTypeBundle<U> remove) {
+        Class<U> type = Helpers.getLambdaGenericType(add, 0);
+        if (add != null) setCompositeCallbackRef("add", type, (inst, 
component, bundle) -> add.accept ((U) inst, bundle));
+        if (change != null) setCompositeCallbackRef("change", type, (inst, 
component, bundle) -> change.accept ((U) inst, bundle));
+        if (remove != null) setCompositeCallbackRef("remove", type, (inst, 
component, bundle) -> remove.accept ((U) inst, bundle));
+        return this;
+  }
+
+    @Override
+    public <U> BundleDependencyBuilder<T> compositeCb(CbTypeComponentBundle<U> 
add) {
+        return compositeCb(add, null, null);
+    }
+
+    @Override
+    public <U> BundleDependencyBuilder<T> compositeCb(CbTypeComponentBundle<U> 
add, CbTypeComponentBundle<U> remove) {
+        return compositeCb(add, null, remove);
+    }
+
+    @Override
+    public <U> BundleDependencyBuilder<T> compositeCb(CbTypeComponentBundle<U> 
add, CbTypeComponentBundle<U> change, CbTypeComponentBundle<U> remove) {
+        Class<U> type = Helpers.getLambdaGenericType(add, 0);
+        if (add != null) setCompositeCallbackRef("add", type, (inst, 
component, bundle) -> add.accept ((U) inst, component, bundle));
+        if (change != null) setCompositeCallbackRef("change", type, (inst, 
component, bundle) -> change.accept ((U) inst, component, bundle));
+        if (remove != null) setCompositeCallbackRef("remove", type, (inst, 
component, bundle) -> remove.accept ((U) inst, component, bundle));
+        return this;
+    }
 
-       @Override
-       public BundleDependencyBuilder propagate(Supplier<Dictionary<?, ?>> 
instance) {
-               if (m_propagateInstance != null || m_propagate) throw new 
IllegalStateException("Propagate callback already set.");
-               m_propagateSupplier = instance;
-               return this;
-       }
-       
        @Override
        public BundleDependency build() {
         DependencyManager dm = m_component.getDependencyManager();
@@ -291,7 +331,7 @@ public class BundleDependencyBuilderImpl
         return dep;
        }
 
-       private <I> BundleDependencyBuilder setCallbackRef(String cb, 
MethodRef<I> ref) {
+       private <U> BundleDependencyBuilder<T> setCallbackRef(String cb, 
MethodRef<U> ref) {
                requiresNoStringCallbacks();
                if (! m_autoConfigInvoked) m_autoConfig = false;
                List<MethodRef<Object>> list = m_refs.computeIfAbsent(cb, l -> 
new ArrayList<>());
@@ -299,21 +339,31 @@ public class BundleDependencyBuilderImpl
                return this;
        }
        
-       @SuppressWarnings("unchecked")
-       private <I> BundleDependencyBuilder 
setComponentInstanceCallbackRef(String cb, String type, MethodRef<I> ref) {
+       private BundleDependencyBuilder<T> setComponentCallbackRef(String cb, 
MethodRef<T> ref) {
                requiresNoStringCallbacks();
                if (! m_autoConfigInvoked) m_autoConfig = false;
                List<MethodRef<Object>> list = m_refs.computeIfAbsent(cb, l -> 
new ArrayList<>());
                list.add((instance, component, bundle) -> {
-                       Stream.of(component.getInstances()).forEach(inst -> {
-                               if (Helpers.getClassName(inst).equals(type)) {
-                                       ref.accept((I) inst, component, bundle);
-                               }
-                       });
+            Object inst = component.getInstance();
+            ref.accept((T) inst, component, bundle);
                });
                return this;
        }
        
+    private <I> BundleDependencyBuilder<T> setCompositeCallbackRef(String cb, 
Class<I> type, MethodRef<I> ref) {
+        requiresNoStringCallbacks();
+        if (! m_autoConfigInvoked) m_autoConfig = false;
+        List<MethodRef<Object>> list = m_refs.computeIfAbsent(cb, l -> new 
ArrayList<>());
+        list.add((instance, component, bundle) -> {
+            Stream.of(component.getInstances()).forEach(inst -> {
+                if (Helpers.getClass(inst).equals(type)) {
+                    ref.accept((I) inst, component, bundle);
+                }
+            });
+        });
+        return this;
+    }
+    
        @SuppressWarnings("unused")
        private Object createCallbackInstance() {
                Object cb = null;

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java?rev=1724333&r1=1724332&r2=1724333&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
 Tue Jan 12 22:45:36 2016
@@ -6,8 +6,8 @@ import java.util.stream.Stream;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.Dependency;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer2;
+import org.apache.felix.dm.builder.lambda.Functions.CbFuture;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeFuture;
 import org.apache.felix.dm.builder.lambda.FutureDependencyBuilder;
 import org.apache.felix.dm.context.AbstractDependency;
 import org.apache.felix.dm.context.DependencyContext;
@@ -15,17 +15,17 @@ import org.apache.felix.dm.context.Event
 import org.apache.felix.dm.context.EventType;
 import org.osgi.service.log.LogService;
 
-public class CompletableFutureDependencyImpl<T> extends 
AbstractDependency<CompletableFutureDependencyImpl<T>>
-               implements FutureDependencyBuilder<T> {
+public class CompletableFutureDependencyImpl<T, F> extends 
AbstractDependency<CompletableFutureDependencyImpl<T, F>> implements 
FutureDependencyBuilder<T, F> {
 
-       private final CompletableFuture<T> m_future;
-       private Consumer<? super T> m_accept;
-       private Consumer2<Object, ? super T> m_accept2;
+       private final CompletableFuture<F> m_future;
        private Component m_comp;
        private boolean m_async;
        private Executor m_exec;
-
-       public CompletableFutureDependencyImpl(Component c, 
CompletableFuture<T> future) {
+    private CbFuture<F> m_accept = (future) -> {};
+    private CbTypeFuture<Object, F> m_accept2;
+    private Class<?> m_accept2Type;
+    
+       public CompletableFutureDependencyImpl(Component c, 
CompletableFuture<F> future) {
                super.setRequired(true);
                m_future = future;
                m_comp = c;
@@ -37,7 +37,7 @@ public class CompletableFutureDependency
         * @param prototype
         *            the existing PathDependency.
         */
-       public CompletableFutureDependencyImpl(Component component, 
CompletableFutureDependencyImpl<T> prototype) {
+       public CompletableFutureDependencyImpl(Component component, 
CompletableFutureDependencyImpl<T, F> prototype) {
                super(prototype);
                m_future = prototype.m_future;
                m_comp = component;
@@ -48,50 +48,68 @@ public class CompletableFutureDependency
                return this;
        }
 
-       @SuppressWarnings("unchecked")
        @Override
-       public FutureDependencyBuilder<T> thenAccept(Consumer<? super T> 
consumer) {
-               m_accept = (Consumer<T>) consumer;
+       public FutureDependencyBuilder<T, F> cb(CbFuture<? super F> consumer) {
+           cb(consumer, false);
                return this;
        }
+       
+       @Override
+       public FutureDependencyBuilder<T, F> cb(CbFuture<? super F> consumer, 
boolean async) {
+           m_accept = m_accept.andThen(future -> consumer.accept(future));
+           m_async = async;
+           return this;
+       }   
+
+    @Override
+    public FutureDependencyBuilder<T, F> cb(CbFuture<? super F> consumer, 
Executor executor) {
+        cb(consumer, true /* async */);
+        m_exec = executor;
+        return this;
+    }
+
 
-       @SuppressWarnings("unchecked")
        @Override
-       public <I> FutureDependencyBuilder<T> thenAccept(Consumer2<I, ? super 
T> consumer) {
-               m_accept2 = (Consumer2<Object, T>) consumer;
+       public FutureDependencyBuilder<T, F> cb(CbTypeFuture<T, ? super F> 
consumer) {
+           cb(consumer, false);
                return this;
        }
 
        @SuppressWarnings("unchecked")
-       @Override
-       public FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> 
consumer) {
-               m_accept = (Consumer<T>) consumer;
-               m_async = true;
+    @Override
+       public FutureDependencyBuilder<T, F> cb(CbTypeFuture<T, ? super F> 
consumer, boolean async) {
+        m_accept2 = (instance, result) -> consumer.accept((T) instance, 
result);
+               m_async = async;
                return this;
        }       
 
-       @Override
-       public <I> FutureDependencyBuilder<T> thenAcceptAsync(Consumer2<I, ? 
super T> consumer) {
-               thenAccept(consumer);
-               m_async = true;
-               return this;
-       }       
 
-       @SuppressWarnings("unchecked")
        @Override
-       public FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> 
consumer, Executor executor) {
-               m_accept = (Consumer<T>) consumer;
-               m_async = true;
+       public FutureDependencyBuilder<T, F> cb(CbTypeFuture<T, ? super F> 
consumer, Executor executor) {
+               cb(consumer, true /* async */);
                m_exec = executor;
                return this;
        }
 
-       @Override
-       public <I> FutureDependencyBuilder<T> thenAcceptAsync(Consumer2<I, ? 
super T> consumer, Executor executor) {
-               thenAccept(consumer);
-               m_async = true;
-               m_exec = executor;
-               return this;
+       public <C> FutureDependencyBuilder<T, F> compositeCb(CbTypeFuture<C, ? 
super F> consumer) {
+           compositeCb(consumer, false);
+           return this;
+       }    
+
+       @SuppressWarnings("unchecked")
+    @Override
+       public <C> FutureDependencyBuilder<T, F> compositeCb(CbTypeFuture<C, ? 
super F> consumer, boolean async) {
+           m_async = async;
+        m_accept2Type = Helpers.getLambdaGenericType(consumer, 0);;
+           m_accept2 = (instance, result) -> consumer.accept((C) instance, 
result);
+           return this;
+       }   
+
+    @Override
+       public <C> FutureDependencyBuilder<T, F> compositeCb(CbTypeFuture<C, ? 
super F> consumer, Executor executor) {
+           compositeCb(consumer, true /* async */);
+           m_exec = executor;
+           return this;
        }
 
        // ---------- DependencyContext interface ----------
@@ -116,7 +134,7 @@ public class CompletableFutureDependency
 
        @Override
        public DependencyContext createCopy() {
-               return new CompletableFutureDependencyImpl<T>(m_comp, this);
+               return new CompletableFutureDependencyImpl<T, F>(m_comp, this);
        }
 
        @Override
@@ -144,33 +162,57 @@ public class CompletableFutureDependency
        public String getType() {
                return "future";
        }
+       
+       /**
+        * Called by DM component implementation when all required dependencies 
are satisfied.
+        */
+    @Override
+    public void invokeCallback(EventType type, Event ... events) {
+        try {
+            switch (type) {
+            case ADDED:
+                F result = events[0].getEvent();
+                if (m_accept2 != null) {
+                    if (m_accept2Type != null) {
+                        // find the component instance that matches the given 
type
+                        Object componentInstance = 
Stream.of(getComponentContext().getInstances())
+                            .filter(instance -> 
Helpers.getClass(instance).equals(m_accept2Type))
+                            .findFirst()
+                            .orElseThrow(() -> new IllegalArgumentException(
+                                "accept callback is not on one of the 
component instances: " + m_accept2 + " (type=" + m_accept2Type + ")"));         
                           
+
+                        m_accept2.accept(componentInstance, result);
+                    } else {
+                        // invoke a method in the main component instance that 
will handle the completed future.
+                        m_accept2.accept(getComponentContext().getInstance(), 
result);
+                    }
+                } else {
+                    // Just invoke the Consumer with the completed future
+                    m_accept.accept(result);
+                }
+                break;
+                
+            default:
+                break;
+            }
+        } catch (Throwable exc) {
+            super.getComponentContext().getLogger().log(LogService.LOG_ERROR, 
"completable future failed", exc);
+        }
+    }
 
        // ---------- Private methods -----------
 
-       private void completed(T result, Throwable error) {
+    /**
+     * Triggers component activation when the future has completed.
+     * @param result
+     * @param error
+     */
+    private void completed(F result, Throwable error) {
                if (error != null) {
                        
super.getComponentContext().getLogger().log(LogService.LOG_ERROR, "completable 
future failed", error);
                } else {
-                       try {
-                               if (m_accept != null) {
-                                       m_accept.accept(result);
-                               } else if (m_accept2 != null) {
-                                       // If using a bi consumer, we need to 
find one of the component instance which type is compatible
-                                       // with the first type of the bi 
consumer method reference.
-                                       String type = 
Helpers.getLambdaGenericType(m_accept2);
-                                       Object componentInstance = 
Stream.of(getComponentContext().getInstances())
-                                               .filter(instance -> 
Helpers.getClassName(instance).equals(type))
-                                               .findFirst()
-                                               .orElseThrow(() -> new 
IllegalArgumentException("accept callback is not on one of the component 
instances: " + m_accept2 + " (type=" + type + ")"));
-                                       
-                                       m_accept2.accept(componentInstance, 
result);
-                               }
-                               m_component.handleEvent(this, EventType.ADDED, 
new Event(""));
-                       }
-
-                       catch (Throwable exc) {
-                               
super.getComponentContext().getLogger().log(LogService.LOG_ERROR, "completable 
future failed", exc);
-                       }
+                   // Will trigger component activation (if other dependencies 
are satisfied), and our invokeCallback method will then be called.
+                   m_component.handleEvent(this, EventType.ADDED, new 
Event(result));
                }
        }
 }

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java?rev=1724333&r1=1724332&r2=1724333&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java
 Tue Jan 12 22:45:36 2016
@@ -9,6 +9,8 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
 import java.util.concurrent.CompletableFuture;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Stream;
@@ -20,13 +22,12 @@ import org.apache.felix.dm.builder.lambd
 import org.apache.felix.dm.builder.lambda.ComponentBuilder;
 import org.apache.felix.dm.builder.lambda.ConfigurationDependencyBuilder;
 import org.apache.felix.dm.builder.lambda.DependencyBuilder;
-import org.apache.felix.dm.builder.lambda.Functions;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponent;
 import org.apache.felix.dm.builder.lambda.Functions.FluentProperties;
 import org.apache.felix.dm.builder.lambda.FutureDependencyBuilder;
 import org.apache.felix.dm.builder.lambda.ServiceDependencyBuilder;
 
-public class ComponentBuilderImpl implements 
ComponentBuilder<ComponentBuilderImpl> {
+public class ComponentBuilderImpl<T> implements ComponentBuilder<T> {
     private final List<DependencyBuilder<?>> m_dependencyBuilders = new 
ArrayList<>();
     private final Component m_component;
     private final boolean m_componentUpdated;
@@ -49,37 +50,38 @@ public class ComponentBuilderImpl implem
     }
         
     @Override
-    public <T> ComponentBuilderImpl autoInject(Class<T> clazz, boolean 
autoConfig) {
+    public <U> ComponentBuilderImpl<T> autoInject(Class<U> clazz, boolean 
autoConfig) {
         m_component.setAutoConfig(clazz, autoConfig);
         return this;
     }
 
     @Override
-    public <T> ComponentBuilderImpl autoInject(Class<T> clazz, String 
instanceName) {
+    public <U> ComponentBuilderImpl<T> autoInject(Class<U> clazz, String 
instanceName) {
         m_component.setAutoConfig(clazz, instanceName);
         return this;
     }
 
     @Override
-    public ComponentBuilderImpl provides(Class<?>... ifaces) {
+    public ComponentBuilderImpl<T> provides(Class<?>... ifaces) {
         m_serviceNames = Stream.of(ifaces).map(c -> 
c.getName()).toArray(String[]::new);
         return this;
     }
 
-    public ComponentBuilderImpl provides(String... ifaces) {
+    @Override
+    public ComponentBuilderImpl<T> provides(String... ifaces) {
         m_serviceNames = ifaces;
         return this;
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public ComponentBuilderImpl properties(Dictionary<?, ?> properties) {
+    public ComponentBuilderImpl<T> properties(Dictionary<?, ?> properties) {
         m_properties = (Dictionary<Object, Object>) properties;
         return this;
     }
 
     @Override
-    public ComponentBuilderImpl properties(String name, Object value, Object 
... rest) {
+    public ComponentBuilderImpl<T> properties(String name, Object value, 
Object ... rest) {
        Objects.nonNull(name);
        Objects.nonNull(value);
         Properties props = new Properties();
@@ -97,7 +99,7 @@ public class ComponentBuilderImpl implem
     }
     
     @Override
-    public ComponentBuilderImpl properties(FluentProperties ... properties) {
+    public ComponentBuilderImpl<T> properties(FluentProperties ... properties) 
{
        Dictionary<Object, Object> props = new Hashtable<>();
        Stream.of(properties).forEach(property -> {
                String name = Helpers.getLambdaParameterName(property, 0);
@@ -112,67 +114,43 @@ public class ComponentBuilderImpl implem
     }
 
     @Override
-    public ComponentBuilderImpl debug(String label) {
+    public ComponentBuilderImpl<T> debug(String label) {
         m_component.setDebug(label);
         return this;
     }
     
     @Override
-    public ComponentBuilderImpl autoAdd(boolean autoAdd) {
+    public ComponentBuilderImpl<T> autoAdd(boolean autoAdd) {
         m_autoAdd = autoAdd;
         return this;
     }
     
-    public boolean autoAdd() {
-       return m_autoAdd;
+    public ComponentBuilderImpl<T> autoAdd() {
+        m_autoAdd = true;
+       return this;
     }
 
-    @Override
-    public <T> ComponentBuilderImpl withService(Class<T> service) {
-        ServiceDependencyBuilder<T> dep = new 
ServiceDependencyBuilderImpl<T>(m_component, service);
-        m_dependencyBuilders.add(dep);
-        return this;
-    }   
-
-    @Override
-    public <T> ComponentBuilderImpl withService(Class<T> service, 
Consumer<ServiceDependencyBuilder<T>> consumer) {
-        ServiceDependencyBuilder<T> dep = new 
ServiceDependencyBuilderImpl<T>(m_component, service);
-        consumer.accept(dep);
-        m_dependencyBuilders.add(dep);
-        return this;
-    }   
-    
-    @Override
-    public ComponentBuilderImpl 
withConfiguration(Consumer<ConfigurationDependencyBuilder> consumer) {
-        ConfigurationDependencyBuilder dep = new 
ConfigurationDependencyBuilderImpl(m_component);
-        consumer.accept(dep);
-        m_dependencyBuilders.add(dep);
-        return this;
+    public boolean isAutoAdd() {
+        return m_autoAdd;
     }
-    
+
+    @SuppressWarnings("unchecked")
     @Override
-    public ComponentBuilderImpl withBundle(Consumer<BundleDependencyBuilder> 
consumer) {
-       BundleDependencyBuilder dep = new 
BundleDependencyBuilderImpl(m_component);
-        consumer.accept(dep);
-        m_dependencyBuilders.add(dep);
-        return this;
-    }
-       
-    public <U> ComponentBuilderImpl withFuture(CompletableFuture<U> future, 
Consumer<FutureDependencyBuilder<U>> consumer) {
-       FutureDependencyBuilder<U> dep = new 
CompletableFutureDependencyImpl<U>(m_component, future);
-       consumer.accept(dep);
-        m_dependencyBuilders.add(dep);
-        return this;
+    public <U> ComponentBuilder<U> impl(U instance) {
+        m_impl = instance;
+        return (ComponentBuilder<U>) this;
     }
     
+    @SuppressWarnings("unchecked")
     @Override
-    public ComponentBuilderImpl impl(Object instance) {
-        m_impl = instance;
-        return this;
+    public <U> ComponentBuilder<U> impl(Class<U> implClass) {
+        m_impl = implClass;
+        return (ComponentBuilder<U>) this;
     }
     
+    @SuppressWarnings("unchecked")
     @Override
-    public <T> ComponentBuilderImpl factory(Supplier<T> create) {
+    public <U> ComponentBuilder<U> factory(Supplier<U> create) {
         Objects.nonNull(create);
         m_factory = new Object() {
             @SuppressWarnings("unused")
@@ -180,26 +158,28 @@ public class ComponentBuilderImpl implem
                 return create.get();
             }
         };
-        return this;
+        return (ComponentBuilder<U>) this;
     }
     
+    @SuppressWarnings("unchecked")
     @Override
-    public <T> ComponentBuilderImpl factory(Supplier<T> supplier, Function<T, 
Object> create) {
+    public <U, V> ComponentBuilder<V> factory(Supplier<U> supplier, 
Function<U, V> create) {
         Objects.nonNull(supplier);
         Objects.nonNull(create);
         
         m_factory = new Object() {
             @SuppressWarnings("unused")
             public Object create() {
-                T factoryImpl = supplier.get();
+                U factoryImpl = supplier.get();
                 return create.apply(factoryImpl);
             }
         }; 
-        return this;
+        return (ComponentBuilder<V>) this;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public <T> ComponentBuilderImpl factory(Supplier<T> create, 
Supplier<Object[]> getComposite) {
+    public <U> ComponentBuilder<U> factory(Supplier<U> create, 
Supplier<Object[]> getComposite) {
         Objects.nonNull(create);
         Objects.nonNull(getComposite);
         
@@ -215,17 +195,17 @@ public class ComponentBuilderImpl implem
             }
         };
         m_factoryHasComposite = true;
-        return this;
+        return (ComponentBuilder<U>) this;
     }
     
     @Override
-    public <T> ComponentBuilderImpl factory(Supplier<T> factorySupplier, 
Function<T, Object> factoryCreate, Function<T, Object[]> factoryGetComposite) {
+    public <U, V> ComponentBuilder<V> factory(Supplier<U> factorySupplier, 
Function<U, V> factoryCreate, Function<U, Object[]> factoryGetComposite) {
         Objects.nonNull(factorySupplier);
         Objects.nonNull(factoryCreate);
         Objects.nonNull(factoryGetComposite);
 
         m_factory = new Object() {
-            T m_factoryInstance;
+            U m_factoryInstance;
             
             @SuppressWarnings("unused")
             public Object create() { 
@@ -239,67 +219,176 @@ public class ComponentBuilderImpl implem
             }
         }; 
         m_factoryHasComposite = true;
+        return (ComponentBuilder<V>) this;
+    }
+        
+    @Override
+    public ComponentBuilderImpl<T> withService(Class<?> service, Class<?> ... 
services) {
+        doWithService(service);
+        for (Class<?> s : services) {
+            doWithService(s);
+        }
+        return this;
+    }   
+
+    private <U> void doWithService(Class<U> service) {
+        ServiceDependencyBuilder<U> dep = new 
ServiceDependencyBuilderImpl<>(m_component, service);
+        m_dependencyBuilders.add(dep);
+    }
+
+    @Override
+    public <U> ComponentBuilderImpl<T> withService(Class<U> service, 
Consumer<ServiceDependencyBuilder<U>> consumer) {
+        ServiceDependencyBuilder<U> dep = new 
ServiceDependencyBuilderImpl<>(m_component, service);
+        consumer.accept(dep);
+        m_dependencyBuilders.add(dep);
+        return this;
+    }   
+    
+    @Override
+    public ComponentBuilderImpl<T> 
withConfiguration(Consumer<ConfigurationDependencyBuilder<T>> consumer) {
+        ConfigurationDependencyBuilder<T> dep = new 
ConfigurationDependencyBuilderImpl<>(m_component);
+        consumer.accept(dep);
+        m_dependencyBuilders.add(dep);
         return this;
     }
     
     @Override
-    public ComponentBuilderImpl onInit(Runnable callback) {
-       return setLifecycleCallback("init", callback);
+    public ComponentBuilderImpl<T> 
withBundle(Consumer<BundleDependencyBuilder<T>> consumer) {
+       BundleDependencyBuilder<T> dep = new 
BundleDependencyBuilderImpl<>(m_component);
+        consumer.accept(dep);
+        m_dependencyBuilders.add(dep);
+        return this;
+    }
+           
+    @Override
+    public <V> ComponentBuilder<T> withFuture(CompletableFuture<V> future, 
Consumer<FutureDependencyBuilder<T, V>> consumer) {
+        FutureDependencyBuilder<T, V> dep = new 
CompletableFutureDependencyImpl<>(m_component, future);
+        consumer.accept(dep);
+        m_dependencyBuilders.add(dep);
+        return this;
+    }
+
+    @Override
+    public final ComponentBuilderImpl<T> init(Consumer<T> callback) {
+       return setLifecycleComponentCallback("init", callback);
+    }
+
+    @Override
+    public final ComponentBuilderImpl<T> init(BiConsumer<T, Component> 
callback) {
+       return setLifecycleComponentCallback("init", callback);        
+    }
+
+    @Override
+    public <U> ComponentBuilderImpl<T> init(Class<U> type, Consumer<U> 
callback) {
+        return setLifecycleCompositeCallback("init", type, callback);
+    }
+   
+    @Override
+    public <U> ComponentBuilderImpl<T> init(Class<U> type, BiConsumer<U, 
Component> callback) {
+        return setLifecycleCompositeCallback("init", type, callback);
+    }
+
+    @Override
+    public ComponentBuilderImpl<T> init(Runnable callback) {
+        return setLifecycleCallback("init", callback);
+    }
+
+    @Override
+    public final ComponentBuilderImpl<T> init(CbComponent callback) {
+        m_lfclCallbacks.put("init", component -> callback.accept(component));
+        return this;
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onInit(Functions.Consumer<T> 
callback) {
-       return setLifecycleCallback("init", callback);
+    public final ComponentBuilderImpl<T> start(Consumer<T> callback) {
+       return setLifecycleComponentCallback("start", callback);
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onInit(Functions.Consumer2<T, 
Component> callback) {
-       return setLifecycleCallback("init", callback);        
+    public final ComponentBuilderImpl<T> start(BiConsumer<T, Component> 
callback) {
+       return setLifecycleComponentCallback("start", callback);        
+    }
+
+    @Override
+    public <U> ComponentBuilderImpl<T> start(Class<U> type, Consumer<U> 
callback) {
+        return setLifecycleCompositeCallback("start", type, callback);
+    }
+   
+    @Override
+    public <U> ComponentBuilderImpl<T> start(Class<U> type, BiConsumer<U, 
Component> callback) {
+        return setLifecycleCompositeCallback("start", type, callback);
     }
 
     @Override
-    public ComponentBuilderImpl onStart(Runnable callback) {
-       return setLifecycleCallback("start", callback);
+    public ComponentBuilderImpl<T> start(Runnable callback) {
+        return setLifecycleCallback("start", callback);
     }
     
     @Override
-    public final <T> ComponentBuilderImpl onStart(Functions.Consumer<T> 
callback) {
-       return setLifecycleCallback("start", callback);
+    public final ComponentBuilderImpl<T> start(CbComponent callback) {
+        m_lfclCallbacks.put("start", component -> callback.accept(component));
+        return this;
+    }
+
+    @Override
+    public final ComponentBuilderImpl<T> stop(Consumer<T> callback) {
+       return setLifecycleComponentCallback("stop", callback);
+    }
+
+    @Override
+    public final ComponentBuilderImpl<T> stop(BiConsumer<T, Component> 
callback) {
+       return setLifecycleComponentCallback("stop", callback);        
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onStart(Functions.Consumer2<T, 
Component> callback) {
-       return setLifecycleCallback("start", callback);        
+    public <U> ComponentBuilderImpl<T> stop(Class<U> type, Consumer<U> 
callback) {
+        return setLifecycleCompositeCallback("stop", type, callback);
+    }
+   
+    @Override
+    public <U> ComponentBuilderImpl<T> stop(Class<U> type, BiConsumer<U, 
Component> callback) {
+        return setLifecycleCompositeCallback("stop", type, callback);
     }
 
     @Override
-    public ComponentBuilderImpl onStop(Runnable callback) {
-       return setLifecycleCallback("stop", callback);
+    public ComponentBuilderImpl stop(Runnable callback) {
+        return setLifecycleCallback("stop", callback);
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onStop(Functions.Consumer<T> 
callback) {
-       return setLifecycleCallback("stop", callback);
+    public final ComponentBuilderImpl<T> stop(CbComponent callback) {
+        m_lfclCallbacks.put("stop", component -> callback.accept(component));
+        return this;
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onStop(Functions.Consumer2<T, 
Component> callback) {
-       return setLifecycleCallback("stop", callback);        
+    public final ComponentBuilderImpl<T> destroy(Consumer<T> callback) {
+       return setLifecycleComponentCallback("destroy", callback);
     }
 
     @Override
-    public ComponentBuilderImpl onDestroy(Runnable callback) {
-       return setLifecycleCallback("destroy", callback);
+    public final ComponentBuilderImpl<T> destroy(BiConsumer<T, Component> 
callback) {
+       return setLifecycleComponentCallback("destroy", callback);        
+    }
+
+    public <U> ComponentBuilderImpl<T> destroy(Class<U> type, Consumer<U> 
callback) {
+        return setLifecycleCompositeCallback("destroy", type, callback);
+    }
+   
+    @Override
+    public <U> ComponentBuilderImpl<T> destroy(Class<U> type, BiConsumer<U, 
Component> callback) {
+        return setLifecycleCompositeCallback("destroy", type, callback);
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onDestroy(Functions.Consumer<T> 
callback) {
-       return setLifecycleCallback("destroy", callback);
+    public ComponentBuilderImpl<T> destroy(Runnable callback) {
+        return setLifecycleCallback("destroy", callback);
     }
 
     @Override
-    public final <T> ComponentBuilderImpl onDestroy(Functions.Consumer2<T, 
Component> callback) {
-       return setLifecycleCallback("destroy", callback);        
+    public final ComponentBuilderImpl<T> destroy(CbComponent callback) {
+        m_lfclCallbacks.put("destroy", component -> 
callback.accept(component));
+        return this;
     }
 
     public Component build() {
@@ -336,47 +425,51 @@ public class ComponentBuilderImpl implem
         return m_component;
     }
 
-    private ComponentBuilderImpl setLifecycleCallback(String method, Runnable 
callback) {
-               m_lfclCallbacks.put(method, component -> callback.run());
+    @SuppressWarnings("unchecked")
+    private ComponentBuilderImpl<T> setLifecycleComponentCallback(String 
method, Consumer<T> callback) {
+        m_lfclCallbacks.put(method, component -> { 
+            callback.accept((T) component.getInstance());
+        });
         return this;
     }
-    
+
     @SuppressWarnings("unchecked")
-    private <T> ComponentBuilderImpl setLifecycleCallback(String method, 
Functions.Consumer<T> callback) {
-       m_lfclCallbacks.put(method, component -> {
-                       String type = Helpers.getLambdaGenericType(callback);
-                       // If the lambda generic type is Component, simply pass 
our component to the lambda's accept method.
-                       // If the type is Object, it means that we are in front 
of a corner case where a Consumer is defined with a wildcard type.
-                       // In this case, assume that the consumer accepts a 
Component. Notice that this may happen may using RxJava.
-                       // Else if the type is another classe, then assumes 
that the lambda is a Consumer<T> where T is one of the component instance 
classes.
-                       if (type.equals(Component.class.getName()) || 
type.equals(Object.class.getName())) {
-                               callback.accept((T) component);
-                       } else {
-                               for (Object instance : 
component.getInstances()) {
-                                       if 
(Helpers.getClassName(instance).equals(type)) {
-                                               callback.accept((T) instance);
-                                               break;
-                                       }
-                               }
-                       }
-       });
+    private ComponentBuilderImpl<T> setLifecycleComponentCallback(String 
method, BiConsumer<T, Component> callback) {
+        m_lfclCallbacks.put(method, component -> { 
+            callback.accept((T) component.getInstance(), component);
+        });
         return this;
     }
 
-    @SuppressWarnings("unchecked")
-       private <T> ComponentBuilderImpl setLifecycleCallback(String method, 
Functions.Consumer2<T, Component> callback) {
-       m_lfclCallbacks.put(method, component -> {              
-                       String type = Helpers.getLambdaGenericType(callback);
-                       for (Object instance : component.getInstances()) {
-                               if 
(Helpers.getClassName(instance).equals(type)) {
-                                       callback.accept((T) instance, 
component);
-                                       break;
-                               }
-                       }
-               });
+    private <U> ComponentBuilderImpl<T> setLifecycleCompositeCallback(String 
method, Class<U> type, Consumer<U> callback) {
+        m_lfclCallbacks.put("init", component -> {
+            for (Object instance : component.getInstances()) {
+                if (Helpers.getClass(instance).equals(type)) {
+                    callback.accept((U) instance);
+                    break;
+                }
+            }
+        });
+        return this;
+    }
+    
+    private <U> ComponentBuilderImpl<T> setLifecycleCompositeCallback(String 
method, Class<U> type, BiConsumer<U, Component> callback) {
+        m_lfclCallbacks.put("init", component -> {
+            for (Object instance : component.getInstances()) {
+                if (Helpers.getClass(instance).equals(type)) {
+                    callback.accept((U) instance, component);
+                    break;
+                }
+            }
+        });
         return this;
     }
 
+    private ComponentBuilderImpl<T> setLifecycleCallback(String method, 
Runnable callback) {
+        m_lfclCallbacks.put(method, component -> callback.run());
+        return this;
+    }
+    
     @SuppressWarnings("unused")
     private void setLifecycleMethodRefs() {
         Object cb = new Object() {

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java?rev=1724333&r1=1724332&r2=1724333&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java
 Tue Jan 12 22:45:36 2016
@@ -1,71 +1,100 @@
 package org.apache.felix.dm.builder.lambda.impl;
 
 import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
+import java.util.function.BiConsumer;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.ConfigurationDependency;
 import org.apache.felix.dm.builder.lambda.ConfigurationDependencyBuilder;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer2;
-import org.apache.felix.dm.context.ComponentContext;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentDictionary;
+import org.apache.felix.dm.builder.lambda.Functions.CbDictionary;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentDictionary;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeDictionary;
 
-public class ConfigurationDependencyBuilderImpl  implements 
ConfigurationDependencyBuilder {
+public class ConfigurationDependencyBuilderImpl<T>  implements 
ConfigurationDependencyBuilder<T> {
     private String m_pid;
     private boolean m_propagate;
-    private Consumer<Dictionary<String, Object>> m_updatedConsumers = (props 
-> {});
-    private boolean m_updatedConsumersSet;
     private final Component m_component;
-    
-       /**
-        * Mapping between component instances and corresponding "updated" 
method references.
-        */
-       private final Map<String, Consumer2<?, Dictionary<String, Object>>> 
m_componentInstanceCbks = new HashMap<>();
+    private String m_updateMethodName;
+    private Object m_updateCallbackInstance;
+    private boolean m_hasMethodRefs;
+    private boolean m_hasReflectionCallback;
 
+    private BiConsumer<Component, Dictionary<String, Object>> m_callbacks = 
(component, props) -> {};
+    
     public ConfigurationDependencyBuilderImpl(Component component) {
         m_component = component;
     }
 
     @Override
-    public ConfigurationDependencyBuilder pid(String pid) {
+    public ConfigurationDependencyBuilder<T> pid(String pid) {
         m_pid = pid;
         return this;
     }
 
     @Override
-    public ConfigurationDependencyBuilder pid(Class<?> pidClass) {
+    public ConfigurationDependencyBuilder<T> pid(Class<?> pidClass) {
         m_pid = pidClass.getName();
         return this;
     }
 
     @Override
-    public ConfigurationDependencyBuilder propagate() {
+    public ConfigurationDependencyBuilder<T> propagate() {
         m_propagate = true;
         return this;
     }
 
     @Override
-    public ConfigurationDependencyBuilder propagate(boolean propagate) {
+    public ConfigurationDependencyBuilder<T> propagate(boolean propagate) {
         m_propagate = propagate;
         return this;
     }
 
-    @Override
-    public <T> ConfigurationDependencyBuilder onUpdate(Consumer2<T, 
Dictionary<String, Object>>  updatedRef) {
-        String instanceType = Helpers.getLambdaGenericType(updatedRef);
-        m_componentInstanceCbks.put(instanceType, updatedRef);        
+    public ConfigurationDependencyBuilder<T> cb(String update) {
+        checkHasNoMethodRefs();
+        m_hasReflectionCallback = true;
+        m_updateMethodName = update;
+        return this;
+    }
+    
+    public ConfigurationDependencyBuilder<T> cb(Object callbackInstance, 
String update) {
+        cb(update);
+        m_updateCallbackInstance = callbackInstance;
         return this;
     }
 
     @Override
-    public ConfigurationDependencyBuilder onUpdate(Consumer<Dictionary<String, 
Object>> updatedConsumer) {
-        m_updatedConsumers = m_updatedConsumers.andThen(props -> 
updatedConsumer.accept(props));
-        m_updatedConsumersSet = true;
-        return null;
+    public ConfigurationDependencyBuilder<T> cb(CbTypeDictionary<T>  callback) 
{
+        return addMethodRef((component, props) -> { 
callback.accept(component.getInstance(), props); });
+    }
+
+    @Override
+    public <U> ConfigurationDependencyBuilder<T> 
compositeCb(CbTypeDictionary<U> callback) {
+        Class<U> type = Helpers.getLambdaGenericType(callback, 0); 
+        return addMethodRef((component, props) -> { 
+            U instance = Helpers.findCompositeInstance(component, type);
+            callback.accept(instance, props);                       
+        });
+    }
+
+    @Override
+    public <U> ConfigurationDependencyBuilder<T> 
compositeCb(CbTypeComponentDictionary<U> callback) {
+        Class<U> type = Helpers.getLambdaGenericType(callback, 0); 
+        return addMethodRef((component, props) -> { 
+            U instance = Helpers.findCompositeInstance(component, type);
+            callback.accept(instance, component, props);                       
+        });
+    }
+    
+    @Override
+    public ConfigurationDependencyBuilder<T> cb(CbDictionary callback) {
+        return addMethodRef((component, props) -> { callback.accept(props); });
+    }
+    
+    @Override
+    public ConfigurationDependencyBuilder<T> cb(CbComponentDictionary 
callback) {
+        return addMethodRef((component, props) -> { callback.accept(component, 
props); });
     }
 
     @Override
@@ -74,30 +103,35 @@ public class ConfigurationDependencyBuil
         Objects.nonNull(m_pid);
         dep.setPid(m_pid);
         dep.setPropagate(m_propagate);
-                
-        if (m_componentInstanceCbks.size() > 0) {
-               // Some method refs have been added on some component 
instances. 
+        if (m_updateMethodName != null) {
+            dep.setCallback(m_updateCallbackInstance, m_updateMethodName);
+        } else {
             dep.setCallback(new Object() {
-                @SuppressWarnings({ "unused", "unchecked" })
+                @SuppressWarnings("unused")
                 void updated(Component comp, Dictionary<String, Object> props) 
{
-                       Stream.of(comp.getInstances()).forEach(instance -> {
-                               Consumer2<Object, Dictionary<String, Object>> 
updatedRef = (Consumer2<Object, Dictionary<String, Object>>) 
m_componentInstanceCbks.get(Helpers.getClassName(instance));
-                               if (updatedRef != null) {
-                                       updatedRef.accept(instance, props);
-                               }
-                       });
-                       m_updatedConsumers.accept(props);
+                    m_callbacks.accept(comp, props);
                 }
             }, "updated", true /* we need component instances before updated 
is called */);
-        } else if (m_updatedConsumersSet) {
-               // Some consumers have been configured, call them on any 
updated properties.
-               dep.setCallback(new Object() {
-                       @SuppressWarnings("unused")
-                       void updated(Dictionary<String, Object> props) {
-                               m_updatedConsumers.accept(props);
-                       }
-               }, "updated");
-        }        
+        }
         return dep;
     }
+    
+    private ConfigurationDependencyBuilder<T> 
addMethodRef(BiConsumer<Component, Dictionary<String, Object>> callback) {
+        checkHasNoReflectionCallbacks();
+        m_hasMethodRefs = true;
+        m_callbacks = m_callbacks.andThen(callback);
+        return this;
+    }
+    
+    private void checkHasNoMethodRefs() {
+        if (m_hasMethodRefs) {
+            throw new IllegalStateException("Can't mix method references with 
reflection based callbacks");
+        }
+    }
+    
+    private void checkHasNoReflectionCallbacks() {
+        if (m_hasReflectionCallback) {
+            throw new IllegalStateException("Can't mix method references with 
reflection based callbacks");
+        }
+    }
 }

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/FactoryPidAdapterBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/FactoryPidAdapterBuilderImpl.java?rev=1724333&r1=1724332&r2=1724333&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/FactoryPidAdapterBuilderImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/FactoryPidAdapterBuilderImpl.java
 Tue Jan 12 22:45:36 2016
@@ -1,98 +1,216 @@
 package org.apache.felix.dm.builder.lambda.impl;
 
 import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Objects;
-import java.util.stream.Stream;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.lambda.ComponentBuilder;
 import org.apache.felix.dm.builder.lambda.FactoryPidAdapterBuilder;
-import org.apache.felix.dm.builder.lambda.Functions.Consumer2;
-
-public class FactoryPidAdapterBuilderImpl 
-       extends ExtendedComponentBase<Object, FactoryPidAdapterBuilderImpl> 
-       implements FactoryPidAdapterBuilder 
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentDictionary;
+import org.apache.felix.dm.builder.lambda.Functions.CbDictionary;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentDictionary;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeDictionary;
+
+public class FactoryPidAdapterBuilderImpl<T> implements 
+        AdapterBase<T, FactoryPidAdapterBuilder<T>>, 
+        FactoryPidAdapterBuilder<T>    
 {
-    protected final Map<String, Consumer2<?, Dictionary<String, Object>>> 
m_callbacks = new HashMap<>();
     private String m_factoryPid;
     private boolean m_propagate;
     private final DependencyManager m_dm;
     private boolean m_autoAdd = true;
+    private BiConsumer<Component, Dictionary<String, Object>> m_callbacks = 
(component, props) -> {};
+    private String m_updateMethodName;
+    private Object m_updateCallbackInstance;
+    private boolean m_hasMethodRefs;
+    private boolean m_hasReflectionCallback;
+    private Consumer<ComponentBuilder<T>> m_compBuilder = (componentBuilder -> 
{});
 
     public FactoryPidAdapterBuilderImpl(DependencyManager dm) {
         m_dm = dm;
     }
+    
+    public void andThenBuild(Consumer<ComponentBuilder<T>> builder) {
+        m_compBuilder = m_compBuilder.andThen(builder);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> FactoryPidAdapterBuilder<U> impl(U impl) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.impl(impl));
+        return (FactoryPidAdapterBuilder<U>) this; 
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U> FactoryPidAdapterBuilder<U> impl(Class<U> implClass) {        
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.impl(implClass));
+        return (FactoryPidAdapterBuilder<U>) this; 
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> FactoryPidAdapterBuilder<U> factory(Supplier<U> create) {       
 
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(create));
+        return (FactoryPidAdapterBuilder<U>) this; 
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U, V> FactoryPidAdapterBuilder<V> factory(Supplier<U> factory, 
Function<U, V> create) {        
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, create));
+        return (FactoryPidAdapterBuilder<V>) this; 
+    }
+        
+    @SuppressWarnings("unchecked")
+    public <U> FactoryPidAdapterBuilder<U> factory(Supplier<U> factory, 
Supplier<Object[]> getComposition) {        
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, getComposition));
+        return (FactoryPidAdapterBuilder<U>) this; 
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U, V> FactoryPidAdapterBuilder<V> factory(Supplier<U> factory, 
Function<U, V> create, Function<U, Object[]> getComposition) {       
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, create, getComposition));
+        return (FactoryPidAdapterBuilder<V>) this; 
+    }
 
     @Override
-    public FactoryPidAdapterBuilderImpl autoAdd(boolean autoAdd) {
+    public FactoryPidAdapterBuilderImpl<T> autoAdd(boolean autoAdd) {
         m_autoAdd = autoAdd;
         return this;
     }
     
-    public boolean autoAdd() {
-       return m_autoAdd;
+    @Override
+    public FactoryPidAdapterBuilderImpl<T> autoAdd() {
+        m_autoAdd = true;
+        return this;
     }
     
+    public boolean isAutoAdd() {
+        return m_autoAdd;
+    }
+
     @Override
-    public FactoryPidAdapterBuilder factoryPid(String pid) {
+    public FactoryPidAdapterBuilder<T> factoryPid(String pid) {
         m_factoryPid = pid;
         return this;
     }
 
     @Override
-    public FactoryPidAdapterBuilder factoryPid(Class<?> pidClass) {
+    public FactoryPidAdapterBuilder<T> factoryPid(Class<?> pidClass) {
         m_factoryPid = pidClass.getName();
         return this;
     }
 
     @Override
-    public FactoryPidAdapterBuilder propagate() {
+    public FactoryPidAdapterBuilder<T> propagate() {
         m_propagate = true;
         return this;
     }
 
     @Override
-    public FactoryPidAdapterBuilder propagate(boolean propagate) {
+    public FactoryPidAdapterBuilder<T> propagate(boolean propagate) {
         m_propagate = propagate;
         return this;
     }
 
-    @Override
-    public <T> FactoryPidAdapterBuilder onUpdate(Consumer2<T, 
Dictionary<String, Object>> callback) {
-        String instanceType = Helpers.getLambdaGenericType(callback);
-        setUpdateRef(instanceType, (T instance, Dictionary<String, Object> 
conf) -> callback.accept(instance, conf));
+    public FactoryPidAdapterBuilder<T> cb(String update) {
+        checkHasNoMethodRefs();
+        m_hasReflectionCallback = true;
+        m_updateMethodName = update;
+        return this;
+    }
+    
+    public FactoryPidAdapterBuilder<T> cb(Object callbackInstance, String 
update) {
+        cb(update);
+        m_updateCallbackInstance = callbackInstance;
         return this;
     }
+    
+    @Override
+    public FactoryPidAdapterBuilder<T> cb(CbTypeDictionary<T> callback) {
+        return addMethodRef((component, props) -> { 
+            callback.accept(component.getInstance(), props);
+        });
+    }
+    
+    @Override
+    public FactoryPidAdapterBuilder<T> cb(CbDictionary callback) {
+        return addMethodRef((component, props) -> { 
+            callback.accept(props);
+        });
+    }
+
+    @Override
+    public FactoryPidAdapterBuilder<T> cb(CbComponentDictionary callback) {
+        return addMethodRef((component, props) -> { 
+            callback.accept(component, props);
+        });
+    }
+
+    @Override
+    public FactoryPidAdapterBuilder<T> cb(CbTypeComponentDictionary<T> 
callback) {
+        return addMethodRef((component, props) -> { 
+            callback.accept(component.getInstance(), component, props); 
+        });
+    }
 
     @Override
+    public <U> FactoryPidAdapterBuilder<T> compositeCb(CbTypeDictionary<U> 
callback) {
+        Class<U> type = Helpers.getLambdaGenericType(callback, 0);
+        return addMethodRef((component, props) -> { 
+            U instance = Helpers.findCompositeInstance(component, type);
+            callback.accept(instance, props);                       
+        });
+    }
+    
+    @Override
+    public <U> FactoryPidAdapterBuilder<T> 
compositeCb(CbTypeComponentDictionary<U> callback) {
+        Class<U> type = Helpers.getLambdaGenericType(callback, 0);
+        return addMethodRef((component, props) -> { 
+            U instance = Helpers.findCompositeInstance(component, type);
+            callback.accept(instance, component, props);                       
+        });
+    }
+    
+    @Override
     public Component build() {        
         Objects.nonNull(m_factoryPid);
-        if (m_callbacks.size() == 0) {
-            throw new IllegalStateException("No callbacks configured in 
factory pid adapter");
+        Component c = null;
+        
+        if (m_hasMethodRefs) {
+            Object wrapCallback = new Object() {
+                @SuppressWarnings("unused")
+                public void updated(Component comp, Dictionary<String, Object> 
conf) {
+                    m_callbacks.accept(comp, conf);
+                }
+            };
+            c = m_dm.createFactoryConfigurationAdapterService(m_factoryPid, 
"updated", m_propagate, wrapCallback);
+        } else {
+            c = m_dm.createFactoryConfigurationAdapterService(m_factoryPid, 
m_updateMethodName, m_propagate, m_updateCallbackInstance);
         }
-        Object wrapCallback = new Object() {
-            @SuppressWarnings({ "unused", "unchecked" })
-            public void updated(Component comp, Dictionary<String, Object> 
conf) {
-                Stream.of(comp.getInstances()).forEach(instance -> {
-                    Consumer2<Object, Dictionary<String, Object>> updateCB = 
-                        (Consumer2<Object, Dictionary<String, Object>>) 
m_callbacks.get(Helpers.getClassName(instance));
-                    if (updateCB != null) {
-                        updateCB.accept(instance, conf);
-                    }
-                });            
- 
-            }
-        };
-        Component c = 
m_dm.createFactoryConfigurationAdapterService(m_factoryPid, "updated", 
m_propagate, wrapCallback);
-        ComponentBuilderImpl cb = new ComponentBuilderImpl(c, false);
+        ComponentBuilderImpl<T> cb = new ComponentBuilderImpl<>(c, false);
         m_compBuilder.accept (cb);
         return cb.build();
     }
-
-    public <T> FactoryPidAdapterBuilder setUpdateRef(String instanceType, 
Consumer2<T, Dictionary<String, Object>> updateCB) {
-        m_callbacks.put(instanceType, updateCB);
+    
+    private FactoryPidAdapterBuilder<T> addMethodRef(BiConsumer<Component, 
Dictionary<String, Object>> callback) {
+        checkHasNoReflectionCallbacks();
+        m_hasMethodRefs = true;
+        m_callbacks = m_callbacks.andThen(callback);
         return this;
     }
+    
+    private void checkHasNoMethodRefs() {
+        if (m_hasMethodRefs) {
+            throw new IllegalStateException("Can't mix method references with 
reflection based callbacks");
+        }
+    }
+    
+    private void checkHasNoReflectionCallbacks() {
+        if (m_hasReflectionCallback) {
+            throw new IllegalStateException("Can't mix method references with 
reflection based callbacks");
+        }
+    }
 }

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/Helpers.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/Helpers.java?rev=1724333&r1=1724332&r2=1724333&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/Helpers.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/Helpers.java
 Tue Jan 12 22:45:36 2016
@@ -11,68 +11,45 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
+import org.apache.felix.dm.Component;
 import org.apache.felix.dm.builder.lambda.Functions.SerializableLambda;
 
-
 /**
- * Helpers related to generics
+ * Various helper methods related to generics and lambda expressions.
  */
 public class Helpers {
        private final static Pattern LAMBDA_INSTANCE_METHOD_TYPE = 
Pattern.compile("(L[^;]+)+");
 
        /**
         * Gets the class name of a given object.
+        * @param obj the object whose class has to be returned.
         */
-       public static String getClassName(Object obj) {
+       public static Class<?> getClass(Object obj) {
                Class<?> clazz = obj.getClass();
                if (Proxy.isProxyClass(clazz)) {
-                       return Proxy.getProxyClass(clazz.getClassLoader(), 
clazz).getName();
+                       return Proxy.getProxyClass(clazz.getClassLoader(), 
clazz);
                }
-               return clazz.getName();
+               return clazz;
        }
        
        /**
-        * Extracts the first actual types of lambda generic parameters.
+        * Extracts the type of a given generic lambda parameter.
+        * Example: for "BiConsumer<String, Integer>", and with 
genericParamIndex=0, this method returns java.lang.String class.
         * 
-        * @param lambda
-        * @return
-        * @throws Exception
-        */
-       public static String getLambdaGenericType(SerializableLambda lambda) {
-               return getLambdaGenericTypes(lambda)[0];
-       }
-       
-       /**
-        * Extracts the actual types of all lambda generic parameters.
+        * @param lambda a lambda expression, which must extends @link {@link 
SerializableLambda} interface.
+        * @param genericParamIndex the index of a given lambda generic 
parameter.
+        * @return the type of the lambda generic parameter that corresponds to 
the <code>genericParamIndex</code>  
         */
-       public static String[] getLambdaGenericTypes(SerializableLambda lambda) 
{
-               // The only portable way to get the actual lambda generic 
parameters can be done using SerializedLambda.
-               SerializedLambda sl = getSerializedLambda(lambda);
-               String lambdaMethodType = sl.getInstantiatedMethodType();
-               Matcher m = 
LAMBDA_INSTANCE_METHOD_TYPE.matcher(lambdaMethodType);
-           List<String> results = new ArrayList<>();
-           while (m.find()) {
-               results.add(m.group().substring(1).replace("/", "."));
-               }
-               return results.toArray(new String[0]);
-       }
-
-    /**
-     * Extracts the actual java method from a given lambda.
-     */
-       public static Method getLambdaMethod(SerializedLambda lambda, 
ClassLoader loader) {
-           String implClassName = lambda.getImplClass().replace('/', '.');
-           Class<?> implClass;
-               try {
-                       implClass = loader.loadClass(implClassName);
-               } catch (ClassNotFoundException e) {
-                   throw new RuntimeException("Lambda Method not found (can 
not instantiate class " + implClassName);
-               }
-
-           return Stream.of(implClass.getDeclaredMethods())
-               .filter(method -> Objects.equals(method.getName(), 
lambda.getImplMethodName()))
-            .findFirst()
-            .orElseThrow(() -> new RuntimeException("Lambda Method not 
found"));
+       @SuppressWarnings("unchecked")
+    public static <T> Class<T> getLambdaGenericType(SerializableLambda lambda, 
int genericParamIndex) {
+           String[] lambdaParams = getGenericTypeStrings(lambda);
+           Class<?> clazz;
+        try {
+            clazz = 
lambda.getClass().getClassLoader().loadClass(lambdaParams[genericParamIndex]);
+        } catch (ClassNotFoundException e) {
+           throw new RuntimeException("Can't load class " + 
lambdaParams[genericParamIndex]);
+        }
+           return (Class<T>) clazz;
        }
        
        /**
@@ -118,4 +95,53 @@ public class Helpers {
            throw new RuntimeException("writeReplace method not found");
        }
 
+    /**
+     * Finds a composite
+     * @param component
+     * @param type
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public static <U> U findCompositeInstance(Component component, Class<U> 
type) {
+        U instance = (U) Stream.of(component.getInstances())
+            .filter(inst -> Objects.equals(Helpers.getClass(inst), type))
+            .findFirst()
+            .orElseThrow(() -> new RuntimeException("Did not find a component 
instance matching type " + type));
+        return instance;                       
+    }
+
+    /**
+     * Extracts the actual types of all lambda generic parameters.
+     * Example: for "BiConsumer<String, Integer>", this method returns 
["java.lang.String", "java.lang.Integer"].
+     */
+    private static String[] getGenericTypeStrings(SerializableLambda lambda) {
+        // The only portable way to get the actual lambda generic parameters 
can be done using SerializedLambda.
+        SerializedLambda sl = getSerializedLambda(lambda);
+        String lambdaMethodType = sl.getInstantiatedMethodType();
+        Matcher m = LAMBDA_INSTANCE_METHOD_TYPE.matcher(lambdaMethodType);
+        List<String> results = new ArrayList<>();
+        while (m.find()) {
+            results.add(m.group().substring(1).replace("/", "."));
+        }
+        return results.toArray(new String[0]);
+    }
+    
+    /**
+     * Extracts the actual java method from a given lambda.
+     */
+    private static Method getLambdaMethod(SerializedLambda lambda, ClassLoader 
loader) {
+        String implClassName = lambda.getImplClass().replace('/', '.');
+        Class<?> implClass;
+        try {
+            implClass = loader.loadClass(implClassName);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Lambda Method not found (can not 
instantiate class " + implClassName);
+        }
+
+        return Stream.of(implClass.getDeclaredMethods())
+            .filter(method -> Objects.equals(method.getName(), 
lambda.getImplMethodName()))
+            .findFirst()
+            .orElseThrow(() -> new RuntimeException("Lambda Method not 
found"));
+    }
+    
 }

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAdapterBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAdapterBuilderImpl.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAdapterBuilderImpl.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAdapterBuilderImpl.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,128 @@
+package org.apache.felix.dm.builder.lambda.impl;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.lambda.ComponentBuilder;
+import org.apache.felix.dm.builder.lambda.ServiceAdapterBuilder;
+
+public class ServiceAdapterBuilderImpl<T, C> extends 
ServiceCallbacksBuilderImpl<T, ServiceAdapterBuilderImpl<T, C>> implements
+    AdapterBase<C, ServiceAdapterBuilder<T, C>>, 
+    ServiceAdapterBuilder<T, C> 
+{      
+    private final Class<?> m_adapteeType;
+    private String m_adapteeFilter;
+    private boolean m_propagate = true;
+    private final DependencyManager m_dm;
+    private boolean m_autoAdd = true;
+    private Consumer<ComponentBuilder<C>> m_compBuilder = (componentBuilder -> 
{});
+
+    public ServiceAdapterBuilderImpl(DependencyManager dm, Class<T> type) {
+        super(type);
+        m_dm = dm;
+        m_adapteeType = type;
+    }    
+
+    @Override
+    public void andThenBuild(Consumer<ComponentBuilder<C>> after) {
+        m_compBuilder = m_compBuilder.andThen(after);        
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAdapterBuilder<T, U> impl(U impl) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.impl(impl));
+        return (ServiceAdapterBuilder<T, U>) this;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAdapterBuilder<T, U> impl(Class<U> impl) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.impl(impl));
+        return (ServiceAdapterBuilder<T, U>) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAdapterBuilder<T, U> factory(Supplier<U> create) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(create));
+        return (ServiceAdapterBuilder<T, U>) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U, V> ServiceAdapterBuilder<T, V> factory(Supplier<U> factory, 
Function<U, V> create) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, create));
+        return (ServiceAdapterBuilder<T, V>) this;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAdapterBuilder<T, U> factory(Supplier<U> factory, 
Supplier<Object[]> getComposition) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, getComposition));
+        return (ServiceAdapterBuilder<T, U>) this;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U, V> ServiceAdapterBuilder<T, V> factory(Supplier<U> factory, 
Function<U, V> create, Function<U, Object[]> getComposition) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, create, getComposition));
+        return (ServiceAdapterBuilder<T, V>) this;
+    }
+
+    @Override
+    public ServiceAdapterBuilderImpl<T, C> autoAdd(boolean autoAdd) {
+        m_autoAdd = autoAdd;
+        return this;
+    }
+    
+    public ServiceAdapterBuilderImpl<T, C> autoAdd() {
+        m_autoAdd = true;
+        return this;
+    }
+
+    public boolean isAutoAdd() {
+        return m_autoAdd;
+    }
+    
+    @Override
+    public ServiceAdapterBuilder<T, C> filter(String adapteeFilter) {
+        m_adapteeFilter = adapteeFilter;
+        return this;
+    }
+
+    @Override
+    public ServiceAdapterBuilder<T, C> propagate() {
+        m_propagate = true;
+        return this;
+    }
+
+    @Override
+    public ServiceAdapterBuilder<T, C> propagate(boolean propagate) {
+        m_propagate = propagate;
+        return this;
+    }
+
+    @Override
+    public Component build() {
+        Objects.nonNull(m_adapteeFilter);
+        
+        String add = m_added, change = m_changed, remove = m_removed, swap = 
m_swapped;
+        Object cbInstance = m_callbackInstance;
+        
+        if (hasRefs()) {
+            // if some method references have been set, use our own callback 
proxy to redispatch events to method refs.        
+               cbInstance = createCallbackInstance();
+            add = "add";
+            change = "change";
+            remove = "remove";
+            swap = m_swapRefs.size() > 0 ? "swap" : null;
+        } 
+
+        Component c = m_dm.createAdapterService
+                       (m_adapteeType, m_adapteeFilter, m_autoConfigField, 
cbInstance, add, change, remove, swap, m_propagate);
+        
+        ComponentBuilderImpl cb = new ComponentBuilderImpl(c, false);
+        // m_compBuilder is a composed consumer that calls in sequence all 
necessary component builder methods. 
+        m_compBuilder.accept (cb);
+        return cb.build();
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAspectBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAspectBuilderImpl.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAspectBuilderImpl.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceAspectBuilderImpl.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,127 @@
+package org.apache.felix.dm.builder.lambda.impl;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.lambda.ComponentBuilder;
+import org.apache.felix.dm.builder.lambda.ServiceAspectBuilder;
+
+public class ServiceAspectBuilderImpl<T, C> extends 
ServiceCallbacksBuilderImpl<T, ServiceAspectBuilderImpl<T, C>> implements
+    AdapterBase<C, ServiceAspectBuilder<T, C>>, 
+    ServiceAspectBuilder<T, C> 
+{    
+    private final DependencyManager m_dm;
+    private final Class<?> m_aspectType;
+    private String m_aspectFilter;
+    private int m_aspectRanking;
+    private boolean m_autoAdd = true;
+    private Consumer<ComponentBuilder<C>> m_compBuilder = (componentBuilder -> 
{});
+
+    public ServiceAspectBuilderImpl(DependencyManager dm, Class<T> type) {
+        super(type);
+        m_dm = dm;
+        m_aspectType = type;
+    }
+
+    @Override
+    public void andThenBuild(Consumer<ComponentBuilder<C>> after) {
+        m_compBuilder = m_compBuilder.andThen(after);        
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAspectBuilderImpl<T, U> impl(U impl) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.impl(impl));
+        return (ServiceAspectBuilderImpl<T, U>) this;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAspectBuilderImpl<T, U> impl(Class<U> impl) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.impl(impl));
+        return (ServiceAspectBuilderImpl<T, U>) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAspectBuilderImpl<T, U> factory(Supplier<U> create) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(create));
+        return (ServiceAspectBuilderImpl<T, U>) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U, V> ServiceAspectBuilderImpl<T, V> factory(Supplier<U> factory, 
Function<U, V> create) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, create));
+        return (ServiceAspectBuilderImpl<T, V>) this;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <U> ServiceAspectBuilderImpl<T, U> factory(Supplier<U> factory, 
Supplier<Object[]> getComposition) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, getComposition));
+        return (ServiceAspectBuilderImpl<T, U>) this;
+    }
+    
+    @SuppressWarnings("unchecked")
+   public <U, V> ServiceAspectBuilderImpl<T, V> factory(Supplier<U> factory, 
Function<U, V> create, Function<U, Object[]> getComposition) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> 
compBuilder.factory(factory, create, getComposition));
+        return (ServiceAspectBuilderImpl<T, V>) this;
+    }
+ 
+    @Override
+    public ServiceAspectBuilderImpl<T, C> autoAdd(boolean autoAdd) {
+        m_autoAdd = autoAdd;
+        return this;
+    }
+    
+    @Override
+    public ServiceAspectBuilderImpl<T, C> autoAdd() {
+        m_autoAdd = true;
+        return this;
+    }
+
+    public boolean isAutoAdd() {
+        return m_autoAdd;
+    }
+
+    @Override
+    public ServiceAspectBuilder<T, C> filter(String aspectFilter) {
+        m_aspectFilter = aspectFilter;
+        return this;
+    }
+
+    @Override
+    public ServiceAspectBuilder<T, C> rank(int ranking) {
+        m_aspectRanking = ranking;
+        return this;
+    }
+
+    @Override
+    public Component build() {
+        Objects.nonNull(m_aspectType);
+        
+        if (m_autoConfigField != null && (hasRefs()|| hasCallbacks())) {
+            throw new IllegalStateException("Can't mix autoConfig fields and 
aspect callbacks.");
+        }
+        
+        Component c = null;
+        if (m_autoConfigField != null) {
+            c = m_dm.createAspectService(m_aspectType, m_aspectFilter, 
m_aspectRanking, m_autoConfigField);
+        } else if (hasRefs()) {        
+            Object cbInstance = createCallbackInstance();
+            String add = "add";
+            String change = "change";
+            String remove = "remove";
+            String swap = m_swapRefs.size() > 0 ? "swap" : null;        
+            c = m_dm.createAspectService(m_aspectType, m_aspectFilter, 
m_aspectRanking, cbInstance, add, change, remove, swap);
+        } else if (hasCallbacks()) {
+            c = m_dm.createAspectService(m_aspectType, m_aspectFilter, 
m_aspectRanking, m_added, m_changed, m_removed, m_swapped);
+        } else {
+            c = m_dm.createAspectService(m_aspectType, m_aspectFilter, 
m_aspectRanking);
+        }
+        ComponentBuilderImpl<C> cb = new ComponentBuilderImpl<>(c, false);
+        // m_compBuilder is a composed consumer that calls in sequence all 
necessary component builder methods. 
+        m_compBuilder.accept (cb);
+        return cb.build();
+    }
+}


Reply via email to