felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1725147 [1/2] - in /felix/sandbox/pderop/dependencymanager-lambda: ./ org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/depe...
Date Sun, 17 Jan 2016 23:38:56 GMT
Author: pderop
Date: Sun Jan 17 23:38:55 2016
New Revision: 1725147

URL: http://svn.apache.org/viewvc?rev=1725147&view=rev
Log:
Added more tests. Added needsInstance method in ConfigurationDependencyBuilder.
Added optional method in ServiceDependencyBuilder.
Added withService(Class service, String filter) method in ComponentBuilder.

Added:
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/InstanceBoundDependencyTest.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependenciesTest.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java
Modified:
    felix/sandbox/pderop/dependencymanager-lambda/TODO
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AdapterWithModifiedInstanceBoundDependencyTest.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/DynamicProxyAspectTest.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/BundleDependencyBuilder.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ComponentBuilder.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ConfigurationDependencyBuilder.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/Functions.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceCallbacksBuilder.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/AdapterBase.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceCallbacksBuilderImpl.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java

Modified: felix/sandbox/pderop/dependencymanager-lambda/TODO
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/TODO?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/TODO (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/TODO Sun Jan 17 23:38:55 2016
@@ -1,13 +1,3 @@
-- add more signatures in ServiceDependencyBuilder (with Component type)
-
-- add factories methods in ComponentImpl that take object/string params (like in original DM API)
-  and update DynamicProxyAspectTest.java
-
-- when a component instance method ref is not found, log an error.
-
-- ConfigurationDependency:
-  * allow to set "needsInstance" flag
-
 - Finish to adapt all DependencyManager integration tests
 
 - add BundeAdapter

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AdapterWithModifiedInstanceBoundDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AdapterWithModifiedInstanceBoundDependencyTest.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AdapterWithModifiedInstanceBoundDependencyTest.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AdapterWithModifiedInstanceBoundDependencyTest.java Sun Jan 17 23:38:55 2016
@@ -120,7 +120,7 @@ public class AdapterWithModifiedInstance
 
         Component a = component(m).impl(new AImpl(e)).provides(A.class).properties(foo -> "bar").build();
         Component b = adapter(m, A.class).cb("addA", "changeA", "removeA").provides(B.class).impl(new BImpl(e)).build();
-        Component c = component(m).impl(new CImpl()).provides(C.class).withService(A.class, s -> s.filter("(foo=bar)")).build();
+        Component c = component(m).impl(new CImpl()).provides(C.class).withService(A.class, "(foo=bar)").build();
                       
         m.add(a);
         m.add(c);

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/DynamicProxyAspectTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/DynamicProxyAspectTest.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/DynamicProxyAspectTest.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/DynamicProxyAspectTest.java Sun Jan 17 23:38:55 2016
@@ -34,11 +34,72 @@ import org.junit.Assert;
  */
 @SuppressWarnings({"rawtypes"})
 public class DynamicProxyAspectTest extends TestBase {
+    public void testImplementGenericAspectWithDynamicProxyAndFactory() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        DynamicProxyHandler.resetCounter();
+        
+        // create two service providers, each providing a different service interface
+        Component sp1 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class).build();
+        Component sp2 = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface2.class).build();
+        
+        // create a dynamic proxy based aspect and hook it up to both services
+        Component a1 = aspect(m, ServiceInterface.class)
+            .rank(10)
+            .autoConfig("m_service")
+            .factory(new Factory(e, ServiceInterface.class, "ServiceInterfaceProxy"), "create")
+            .build();
+        
+        Component a2 = aspect(m, ServiceInterface2.class)
+            .rank(10)
+            .autoConfig("m_service")
+            .factory(new Factory(e, ServiceInterface2.class, "ServiceInterfaceProxy2"), "create")
+            .build();
+
+        // create a client that invokes a method on boths services, validate that it goes
+        // through the proxy twice
+        Component sc = component(m)
+            .impl(new ServiceConsumer(e))
+            .withService(ServiceInterface.class, ServiceInterface2.class).build();
+        
+        // register both producers, validate that both services are started
+        m.add(sp1);
+        e.waitForStep(1, 2000);
+        m.add(sp2);
+        e.waitForStep(2, 2000);
+        
+        // add both aspects, and validate that both instances have been created
+        m.add(a1);
+        m.add(a2);
+        e.waitForStep(4, 4000);
+        
+        // add the client, which will automatically invoke both services
+        m.add(sc);
+        
+        // wait until both services have been invoked
+        e.waitForStep(6, 4000);
+        
+        // make sure the proxy has been called twice
+        Assert.assertEquals("Proxy should have been invoked this many times.", 2, DynamicProxyHandler.getCounter());
+        
+        m.remove(sc);
+        m.remove(a2);
+        m.remove(a1);
+        m.remove(sp2);
+        m.remove(sp1);
+        m.remove(a2);
+        m.remove(a1);
+    }
+
     public void testImplementGenericAspectWithDynamicProxyAndFactoryRef() {
         DependencyManager m = getDM();
         // helper class that ensures certain steps get executed in sequence
         Ensure e = new Ensure();
         
+        DynamicProxyHandler.resetCounter();
+
         // create two service providers, each providing a different service interface
         Component sp1 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class).build();
         Component sp2 = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface2.class).build();
@@ -81,15 +142,7 @@ public class DynamicProxyAspectTest exte
         m.remove(sp2);
         m.remove(sp1);
         m.remove(a2);
-        m.remove(a1);
-        
-        try {
-            Thread.sleep(2000);
-        }
-        catch (InterruptedException e1) {
-            // TODO Auto-generated catch block
-            e1.printStackTrace();
-        }
+        m.remove(a1);        
     }
     
     static interface ServiceInterface {
@@ -176,6 +229,10 @@ public class DynamicProxyAspectTest exte
         public static int getCounter() {
             return m_counter;
         }
+        
+        public static void resetCounter() {
+            m_counter = 0;
+        }
     }
     
     static class Factory {

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java?rev=1725147&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/FactoryInjectedWithConfigurationBeforeTheCreateMethod.java Sun Jan 17 23:38:55 2016
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.builder.lambda.itest;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
+import static org.apache.felix.dm.builder.lambda.Cb.*;
+
+
+/**
+ * Use case: one component is instantiated using another factory object, and the 
+ * factory object needs the configuration before the factory.create method is called.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FactoryInjectedWithConfigurationBeforeTheCreateMethod extends TestBase {
+    Ensure m_e;
+    
+    public void testServiceInjection() {
+        DependencyManager m = getDM();
+        m_e = new Ensure();
+        
+        // Create the component that creates a configuration.
+        Component configurator = component(m).impl(new Configurator("foobar")).withService(ConfigurationAdmin.class).build();
+        
+        // Create the object that has to be injected with the configuration before its create method is called.
+        MyFactory factory = new MyFactory();
+        
+        // Create the Component for the MyComponent class that is created using the factory above.
+        Component myComponent = component(m).factory(factory, "create").withConfiguration(b->b.pid("foobar").cb(factory, "updated")).build();
+        
+        // provide the configuration
+        m.add(configurator);
+        
+        m.add(myComponent);
+        m_e.waitForStep(4, 10000);
+        m.remove(myComponent);
+        m.remove(configurator);
+    }
+    
+    public void testServiceInjectionRef() {
+        DependencyManager m = getDM();
+        m_e = new Ensure();
+        
+        // Create the component that creates a configuration.
+        Component configurator = component(m).impl(new Configurator("foobar")).withService(ConfigurationAdmin.class).build();
+        
+        // Create the object that has to be injected with the configuration before its create method is called.
+        MyFactory factory = new MyFactory();
+        
+        // Create the Component for the MyComponent class that is created using the factory above.
+        Component myComponent = component(m).factory(factory, "create").withConfiguration(b->b.pid("foobar").cbi(factory::updated)).build();
+        
+        // provide the configuration
+        m.add(configurator);
+        
+        m.add(myComponent);
+        m_e.waitForStep(4, 10000);
+        m.remove(myComponent);
+        m.remove(configurator);
+    }
+
+    class Configurator {
+        private volatile ConfigurationAdmin m_ca;
+        Configuration m_conf;
+        final String m_pid;
+        
+        public Configurator(String pid) {
+            m_pid = pid;
+        }
+
+        public void init() {
+            try {
+                Assert.assertNotNull(m_ca);
+                m_e.step(1);
+                m_conf = m_ca.getConfiguration(m_pid, null);
+                Hashtable<String, Object> props = new Hashtable<>();
+                props.put("testkey", "testvalue");
+                m_conf.update(props);
+            }
+            catch (IOException e) {
+                Assert.fail("Could not create configuration: " + e.getMessage());
+            }
+        }
+        
+        public void destroy() throws IOException {
+            m_conf.delete();  
+        }
+    }
+
+    public class MyFactory {
+        public void updated(Dictionary<String, Object> conf) {
+            Assert.assertNotNull("configuration is null", conf);
+            m_e.step(2);
+        }
+        
+        public MyComponent create() {
+            m_e.step(3);
+            return new MyComponent();
+        }
+    }
+    
+    public class MyComponent {
+        void start() {
+            m_e.step(4);
+        }        
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/InstanceBoundDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/InstanceBoundDependencyTest.java?rev=1725147&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/InstanceBoundDependencyTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/InstanceBoundDependencyTest.java Sun Jan 17 23:38:55 2016
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.builder.lambda.itest;
+
+import static org.apache.felix.dm.builder.lambda.Cb.ADD;
+import static org.apache.felix.dm.builder.lambda.Cb.CHG;
+import static org.apache.felix.dm.builder.lambda.Cb.REM;
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This test does some injection tests on components being in INSTANTIATED_AND_WAITING_FOR_REQUIRED state.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class InstanceBoundDependencyTest extends TestBase {
+    Ensure m_e;
+    
+    public void testServiceInjection() {
+        DependencyManager m = getDM();
+        m_e = new Ensure();
+        
+        // Create a "C" component: it depends on some S1 services, and on some S2 instance-bound services (declared from C.init() method)        
+        C cimpl = new C();
+        Component c = component(m).impl(cimpl)
+            .withService(S1.class, sb->sb.cb("addS1", "changeS1", "removeS1").autoConfig(true)).build();
+        m.add(c);
+        
+        // Add S1 (s1_1): C.add(S1 s1) is called, then init() is called where a dependency is declared on S2
+        Hashtable s1_1_props = new Hashtable();
+        s1_1_props.put("name", "s1_1");
+        s1_1_props.put(Constants.SERVICE_RANKING, new Integer(10));
+        S1Impl s1_1_impl = new S1Impl();
+        Component s1_1 = component(m).impl(s1_1_impl).provides(S1.class.getName(), s1_1_props).build();
+        m.add(s1_1);
+        m_e.waitForStep(1, 5000); // wait until C.init called
+        ServiceReference ref = cimpl.getS1("s1_1");
+        Assert.assertNotNull(ref);
+        Assert.assertNotNull(cimpl.getS1());
+        Assert.assertEquals(s1_1_impl, cimpl.getS1());
+        
+        // At this point, MyComponent is in INSTANTIATED_AND_WAITING_FOR_REQUIRED state. 
+        // add now add another higher ranked S1 (s1_2) instance. C.add(s1_2) method should be called (the S1 dependency 
+        // is not instance bound), and m_s1 autoconfig field should be updated.
+        Hashtable s1_2_props = new Hashtable();
+        s1_2_props.put(Constants.SERVICE_RANKING, new Integer(20));
+        s1_2_props.put("name", "s1_2");
+        S1Impl s1_2_impl = new S1Impl();
+        Component s1_2 = component(m).impl(s1_2_impl).provides(S1.class.getName(), s1_2_props).build();
+        m.add(s1_2);
+        ref = cimpl.getS1("s1_2");
+        Assert.assertNotNull(ref);
+        Assert.assertNotNull(cimpl.getS1()); 
+        Assert.assertEquals(s1_2_impl, cimpl.getS1()); // must return s1_2 with ranking = 20
+
+        // Now, change the s1_1 service properties: C.changed(s1_1) should be called, and C.m_s1AutoConfig should be updated
+        s1_1_props.put(Constants.SERVICE_RANKING, new Integer(30));
+        s1_1.setServiceProperties(s1_1_props);
+        ref = cimpl.getS1("s1_1");
+        Assert.assertNotNull(ref);
+        Assert.assertEquals(new Integer(30), ref.getProperty(Constants.SERVICE_RANKING));
+        Assert.assertNotNull(cimpl.getS1());
+        Assert.assertEquals(s1_1_impl, cimpl.getS1());
+        
+        // Now, remove the s1_1: C.remove(s1_1) should be called, and C.m_s1AutoConfig should be updated
+        m.remove(s1_1);
+        ref = cimpl.getS1("s1_1");
+        Assert.assertNull(cimpl.getS1("s1_1"));
+        Assert.assertNotNull(cimpl.getS1());
+        Assert.assertEquals(s1_2_impl, cimpl.getS1());
+        m.clear();
+    }
+    
+    // C component depends on some S1 required services
+    public interface S1 {
+    }
+    
+    public class S1Impl implements S1 {
+    }
+    
+    public interface S2 {        
+    }
+    
+    public class S2Impl implements S2 {        
+    }
+    
+    // Our "C" component: it depends on S1 (required) and S2 (required/instance bound)
+    class C {        
+        final Map<String, ServiceReference> m_s1Map = new HashMap();
+        final Map<String, ServiceReference> m_s2Map = new HashMap();
+        volatile S1 m_s1; // auto configured
+        
+        S1 getS1() {
+            return m_s1;
+        }
+
+        void addS1(ServiceReference s1) {
+            m_s1Map.put((String) s1.getProperty("name"), s1);
+        }
+        
+        void changeS1(ServiceReference s1) {
+            m_s1Map.put((String) s1.getProperty("name"), s1);
+        }
+        
+        void removeS1(ServiceReference s1) {
+            m_s1Map.remove((String) s1.getProperty("name"));
+        }
+        
+        void addS2(ServiceReference s2) {
+            m_s2Map.put((String) s2.getProperty("name"), s2);
+        }
+        
+        void changeS2(ServiceReference s2) {
+            m_s2Map.put((String) s2.getProperty("name"), s2);
+        }
+        
+        void removeS2(ServiceReference s2) {
+            m_s2Map.remove((String) s2.getProperty("name"));
+        }
+        
+        ServiceReference getS1(String name) {
+            return m_s1Map.get(name);
+        }
+        
+        ServiceReference getS2(String name) {
+            return m_s2Map.get(name);
+        }
+        
+        void init(Component c) {
+            component(c, comp->comp.withService(S2.class, srv -> srv.cb(ADD, C::addS2).cb(CHG, C::changeS2).cb(REM, C::removeS2)));
+            m_e.step(1);
+        }
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependenciesTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependenciesTest.java?rev=1725147&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependenciesTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependenciesTest.java Sun Jan 17 23:38:55 2016
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.builder.lambda.itest;
+
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class MultipleExtraDependenciesTest extends TestBase {
+    /**
+     * Check that list of extra dependencies (defined from init method) are handled properly.
+     * The extra dependencies are added using a List object (Component.add(List)).
+     * A component c1 will define two extra dependencies over *available* c4/c5 services.
+     */
+     public void testWithTwoAvailableExtraDependency() {   
+         DependencyManager m = getDM();
+         // Helper class that ensures certain steps get executed in sequence
+         Ensure e = new Ensure();
+         Component c1 = component(m).provides(Service1.class).impl(new MyComponent1(e)).withService(Service2.class, srv->srv.autoConfig("m_service2")).build();
+         Component c2 = component(m).impl(new MyComponent2(e)).withService(Service1.class, srv->srv.required(false).autoConfig(false).cb("added")).build();
+         Component c3 = component(m).provides(Service2.class).impl(Service2Impl.class).build();
+         Component c4 = component(m).impl(Service3Impl1.class).provides(Service3.class, type -> "xx").build();
+         Component c5 = component(m).impl(Service3Impl2.class).provides(Service3.class, type -> "yy").build();
+
+         System.out.println("\n+++ Adding c2 / MyComponent2");
+         m.add(c2);
+         System.out.println("\n+++ Adding c3 / Service2");
+         m.add(c3);
+         System.out.println("\n+++ Adding c4 / Service3(xx)");
+         m.add(c4);
+         System.out.println("\n+++ Adding c5 / Service3(yy)");
+         m.add(c5);
+         System.out.println("\n+++ Adding c1 / MyComponent1");
+         // c1 have declared two extra dependency on Service3 (xx/yy).
+         // both extra dependencies are available, so the c1 component should be started immediately.
+         m.add(c1);
+         e.waitForStep(3, 3000);
+         m.clear();
+     }
+
+    /**
+     * Check that list of extra dependencies (defined from init method) are handled properly.
+     * The extra dependencies are added using a List object (Component.add(List)).
+     * A component c1 will define two extra dependencies over c4/c5. At the point c1.init()
+     * is adding the two extra dependencies from its init method, c4 is available, but not c5.
+     * So, c1 is not yet activated.
+     * Then c5 is added, and it triggers the c1 activation ...
+     */
+    public void testWithOneAvailableExtraDependency() {  
+        DependencyManager m = getDM();
+        // Helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        Component c1 = component(m).provides(Service1.class).impl(new MyComponent1(e)).withService(Service2.class, srv->srv.autoConfig("m_service2")).build();
+        Component c2 = component(m).impl(new MyComponent2(e)).withService(Service1.class, srv->srv.required(false).autoConfig(false).cb("added")).build();
+        Component c3 = component(m).provides(Service2.class).impl(Service2Impl.class).build();
+        Component c4 = component(m).impl(Service3Impl1.class).provides(Service3.class, type -> "xx").build();
+        Component c5 = component(m).impl(Service3Impl2.class).provides(Service3.class, type -> "yy").build();
+
+        System.out.println("\n+++ Adding c2 / MyComponent2");
+        m.add(c2);
+        System.out.println("\n+++ Adding c3 / Service2");
+        m.add(c3);
+        System.out.println("\n+++ Adding c4 / Service3(xx)");
+        m.add(c4);
+        System.out.println("\n+++ Adding c1 / MyComponent1");
+        m.add(c1);
+
+        // c1 have declared two extra dependency on Service3 (xx/yy).
+        // So, because we have not yet added c5 (yy), c1 should not be started currently.
+        // But, now, we'll add c5 (Service3/yy) and c1 should then be started ...
+        System.out.println("\n+++ Adding c5 / Service3(yy)");
+        m.add(c5);
+        e.waitForStep(3, 3000);
+        m.clear();
+    }
+
+
+    public interface Service1 {}
+    public interface Service2 {}
+    public interface Service3 {}
+
+    public static class Service2Impl implements Service2 {}
+    public static class Service3Impl1 implements Service3 {}
+    public static class Service3Impl2 implements Service3 {}
+
+    public static class MyComponent1 implements Service1 {
+        Service2 m_service2;
+        Service3 m_service3_xx;
+        Service3 m_service3_yy;
+        Ensure m_ensure;
+        
+        public MyComponent1(Ensure e) {
+            m_ensure = e;
+        }
+
+        void init(Component c) {
+            m_ensure.step(1);
+            // Service3/xx currently available
+            // Service3/yy not yet available
+
+            component(c, comp -> comp
+                .withService(Service3.class, srv->srv.filter("(type=xx)").autoConfig("m_service3_xx"))
+                .withService(Service3.class, srv->srv.filter("(type=yy)").autoConfig("m_service3_yy")));
+        }
+        
+        void start() {
+            System.out.println("MyComponent1.start");
+            Assert.assertNotNull(m_service2);
+            Assert.assertNotNull(m_service3_xx);
+            Assert.assertNotNull(m_service3_yy);
+            m_ensure.step(2);
+        }
+    }
+    
+    public static class MyComponent2 {
+        Ensure m_ensure;
+        
+        public MyComponent2(Ensure e) {
+            m_ensure = e;
+        }
+
+        void added(Service1 s1) {
+            System.out.println("MyComponent2.bind(" + s1 + ")");
+            Assert.assertNotNull(s1);
+            m_ensure.step(3);
+        }
+        
+        void start() {
+            System.out.println("MyComponent2.start");
+        }
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest.java?rev=1725147&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest.java Sun Jan 17 23:38:55 2016
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.builder.lambda.itest;
+
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+/**
+ * Test which validates multi-dependencies combination.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "serial"})
+public class MultipleExtraDependencyTest extends TestBase {
+    public void testMultipleExtraDependencies()
+    {
+        DependencyManager m = getDM();
+        Ensure e = new Ensure();
+        
+        Component sp2 = component(m)
+              .impl(ServiceProvider2.class).provides(ServiceProvider2.class)
+              .withService(Runnable.class, srv->srv.filter("(foo=bar)").required(false).autoConfig("m_runnable"))
+              .withService(Sequencer.class, srv->srv.cb("bind"))
+              .cb(null, "start", "stop", null)
+              .composition("getComposition")
+              .build();
+
+        Component sp = component(m)
+              .impl(ServiceProvider.class)
+              .provides(ServiceInterface.class.getName(), 
+                            new Hashtable() {{ put("foo", "bar"); }})
+              .withService(Sequencer.class, srv->srv.autoConfig("m_sequencer"))
+              .withService(ServiceProvider2.class, srv->srv.cb("bind", "unbind"))
+              .cb(null, "start", "stop", null)
+              .build();
+        
+        Component sc = component(m)
+              .impl(ServiceConsumer.class)
+              .withService(Sequencer.class, srv->srv.autoConfig("m_sequencer"))
+              .withService(ServiceInterface.class, srv->srv.filter("(foo=bar)").autoConfig("m_service"))
+              .cb(null, "start", "stop", null)
+              .build();
+        
+        Component sequencer = component(m)
+           .impl(new SequencerImpl(e))
+           .provides(Sequencer.class.getName())
+           .build();
+           
+        m.add(sp2);
+        m.add(sp);
+        m.add(sc);
+        m.add(sequencer);
+        
+        // Check if ServiceProvider component have been initialized orderly
+        e.waitForStep(7, 5000);
+        
+        // Stop the test.annotation bundle
+        m.remove(sequencer);
+        m.remove(sp);
+        m.remove(sp2);
+        m.remove(sc);
+        
+        // And check if ServiceProvider2 has been deactivated orderly
+        e.waitForStep(11, 5000);
+    }
+    
+    public interface Sequencer
+    {
+        void step();
+        void step(int step);
+        void waitForStep(int step, int timeout);
+    }
+    
+    public static class SequencerImpl implements Sequencer {
+        Ensure m_ensure;
+        
+        public SequencerImpl(Ensure e)
+        {
+            m_ensure = e;
+        }
+        
+        public void step()
+        {
+            m_ensure.step();
+        }
+
+        public void step(int step)
+        {
+            m_ensure.step(step);
+        }
+
+        public void waitForStep(int step, int timeout)
+        {
+            m_ensure.waitForStep(step, timeout);
+        }  
+    }
+    
+    public interface ServiceInterface
+    {
+        public void doService();
+    }
+    
+    public static class ServiceConsumer
+    {
+        volatile Sequencer m_sequencer;
+        volatile ServiceInterface m_service;
+
+        void start()
+        {
+            m_sequencer.step(6);
+            m_service.doService();
+        }
+
+        void stop()
+        {
+            m_sequencer.step(8);
+        }
+    }
+    
+    public static class ServiceProvider implements ServiceInterface
+    {
+        Sequencer m_sequencer;
+        ServiceProvider2 m_serviceProvider2;
+
+        void bind(ServiceProvider2 provider2)
+        {
+            m_serviceProvider2 = provider2;
+        }
+
+        void start()
+        {
+            m_serviceProvider2.step(4);
+            m_sequencer.step(5);
+        }
+
+        void stop()
+        {
+            m_sequencer.step(9);
+        }
+
+        void unbind(ServiceProvider2 provider2)
+        {
+            m_sequencer.step(10);
+        }
+
+        public void doService()
+        {
+            m_sequencer.step(7);
+        }
+    }
+
+    public static class ServiceProvider2
+    {
+        Composite m_composite = new Composite();
+        Sequencer m_sequencer;
+        Runnable m_runnable;
+
+        void bind(Sequencer seq)
+        {
+            m_sequencer = seq;
+            m_sequencer.step(1);
+        }
+
+        void start()
+        {
+            m_sequencer.step(3);
+            m_runnable.run(); // NullObject
+        }
+
+        public void step(int step) // called by ServiceProvider.start() method 
+        { 
+            m_sequencer.step(step);
+        }
+        
+        void stop()
+        {
+            m_sequencer.step(11);
+        }
+
+        Object[] getComposition()
+        {
+            return new Object[] { this, m_composite };
+        }
+    }
+    
+    public static class Composite
+    {
+        void bind(Sequencer seq)
+        {
+            seq.step(2);
+        }
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java?rev=1725147&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleExtraDependencyTest2.java Sun Jan 17 23:38:55 2016
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.builder.lambda.itest;
+
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
+
+/**
+ * Tests for extra dependencies which are declared from service's init method.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "serial"})
+public class MultipleExtraDependencyTest2 extends TestBase {
+    public void testMultipleExtraDependencies() {
+        DependencyManager m = getDM();
+        Ensure e = new Ensure();
+        
+        Component sp2 = component(m)
+            .impl(ServiceProvider2.class)
+            .provides(ServiceProvider2.class)
+            .cb("init", "start", "stop", null)
+            .composition("getComposition").build();
+        
+        Component sp = component(m)
+              .impl(ServiceProvider.class)
+              .provides(ServiceInterface.class, "foo", "bar")                            
+              .cb("init", "start", "stop", null)
+              .build();
+        
+        Component sc = component(m)
+              .impl(ServiceConsumer.class)
+              .cb("init", "start", "stop", null)
+              .build();
+        
+        // Provide the Sequencer service to the MultipleAnnotationsTest class.
+        Component sequencer =  component(m)
+            .impl(new SequencerImpl(e))
+            .provides(Sequencer.class)
+            .build();
+        
+        m.add(sp2);
+        m.add(sp);
+        m.add(sc);
+        m.add(sequencer);
+
+        // Check if the test.annotation components have been initialized orderly
+        e.waitForStep(7, 10000);
+        
+        // Stop the test.annotation bundle
+        m.remove(sequencer);
+        m.remove(sp);
+        m.remove(sp2);
+        m.remove(sc);
+        
+//        m.remove(sp2);
+//        m.remove(sc);
+//        m.remove(sp);
+//        m.remove(sequencer);
+        
+
+        
+        // And check if the test.annotation bundle has been deactivated orderly
+        e.waitForStep(11, 10000);
+        m.clear();
+    }
+    
+    public interface Sequencer
+    {
+        void step();
+        void step(int step);
+        void waitForStep(int step, int timeout);
+    }
+    
+    public static class SequencerImpl implements Sequencer {
+        final Ensure m_ensure;
+        
+        public SequencerImpl(Ensure e)
+        {
+            m_ensure = e;
+        }
+        
+        public void step()
+        {
+            m_ensure.step();
+        }
+
+        public void step(int step)
+        {
+            m_ensure.step(step);
+        }
+
+        public void waitForStep(int step, int timeout)
+        {
+            m_ensure.waitForStep(step, timeout);
+        }  
+    }
+    
+    public interface ServiceInterface
+    {
+        public void doService();
+    }
+    
+    public static class ServiceConsumer {
+        volatile Sequencer m_sequencer;
+        volatile ServiceInterface m_service;
+        volatile Dependency m_d1, m_d2;
+
+        public void init(Component s) {
+            component(s, comp->comp
+                .withService(Sequencer.class, srv->srv.autoConfig("m_sequencer"))
+                .withService(ServiceInterface.class, srv->srv.filter("(foo=bar)").autoConfig("m_service")));
+        }
+        
+        void start() {
+            m_sequencer.step(6);
+            m_service.doService();
+        }
+
+        void stop() {
+            m_sequencer.step(8);
+        }
+    }
+    
+    public static class ServiceProvider implements ServiceInterface
+    {
+        volatile Sequencer m_sequencer;
+        volatile ServiceProvider2 m_serviceProvider2;
+        volatile ServiceDependency m_d1, m_d2;
+
+        public void init(Component c)
+        {
+            component(c, comp->comp
+                .withService(Sequencer.class, srv->srv.autoConfig("m_sequencer"))
+                .withService(ServiceProvider2.class, srv->srv.cb("bind", "unbind")));
+        }
+        
+        void bind(ServiceProvider2 provider2)
+        {
+            m_serviceProvider2 = provider2;
+        }
+
+        void start()
+        {
+            m_serviceProvider2.step(4);
+            m_sequencer.step(5);
+        }
+
+        void stop()
+        {
+            m_sequencer.step(9);
+        }
+
+        void unbind(ServiceProvider2 provider2)
+        {
+            m_sequencer.step(10);
+        }
+
+        public void doService()
+        {
+            m_sequencer.step(7);
+        }
+    }
+
+    public static class ServiceProvider2
+    {
+        final Composite m_composite = new Composite();
+        volatile Sequencer m_sequencer;
+        volatile Runnable m_runnable;
+        volatile ServiceDependency m_d1, m_d2;
+
+        public void init(Component c)
+        {
+            component(c, comp->comp
+		      .withService(Runnable.class, srv->srv.optional().filter("(foo=bar)"))
+		      .withService(Sequencer.class, srv->srv.cb("bind")));
+        }
+        
+        void bind(Sequencer seq)
+        {
+            System.out.println("ServiceProvider2.bind(" + seq + ")");
+            m_sequencer = seq;
+            m_sequencer.step(1);
+        }
+
+        void start()
+        {
+            System.out.println("ServiceProvider2.start: m_runnable=" + m_runnable + ", m_sequencer = " + m_sequencer);
+            m_sequencer.step(3);
+            m_runnable.run(); // NullObject
+        }
+
+        public void step(int step) // called by ServiceProvider.start() method 
+        { 
+            m_sequencer.step(step);
+        }
+        
+        void stop()
+        {
+            m_sequencer.step(11);
+        }
+
+        Object[] getComposition()
+        {
+            return new Object[] { this, m_composite };
+        }
+    }
+    
+    public static class Composite
+    {
+        void bind(Sequencer seq)
+        {
+            seq.step(2);
+        }
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java?rev=1725147&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/MultipleServiceDependencyTest.java Sun Jan 17 23:38:55 2016
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.builder.lambda.itest;
+
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.Constants;
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.*;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "serial"})
+public class MultipleServiceDependencyTest extends TestBase {
+   public void testMultipleServiceRegistrationAndConsumption() {
+       DependencyManager m = getDM();
+       // helper class that ensures certain steps get executed in sequence
+       Ensure e = new Ensure();
+       // create a service provider and consumer
+       Component provider = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
+       Component providerWithHighRank = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface.class.getName(), Constants.SERVICE_RANKING, Integer.valueOf(5)).build();
+       Component consumer = component(m).impl(new ServiceConsumer(e)).withService(ServiceInterface.class).build();
+       m.add(provider);
+       m.add(providerWithHighRank);
+       m.add(consumer);
+       e.waitForStep(3, 5000);
+       m.remove(providerWithHighRank);
+       e.step(4);
+       e.waitForStep(5, 5000);
+       m.remove(provider);
+       m.remove(consumer);
+       e.waitForStep(6, 5000);
+   }
+
+   public void testReplacementAutoConfig() {
+       DependencyManager m = getDM();
+       // helper class that ensures certain steps get executed in sequence
+       Ensure e = new Ensure();
+       // create a service provider and consumer
+       Component provider = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
+       Component provider2 = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface.class.getName()).build();
+       Component consumer = component(m).impl(new ServiceConsumer(e)).withService(ServiceInterface.class).build();
+       m.add(provider2);
+       m.add(consumer);
+       e.waitForStep(3, 5000);
+       m.add(provider);
+       m.remove(provider2);
+       e.step(4);
+       e.waitForStep(5, 5000);
+       m.remove(provider);
+       m.remove(consumer);
+       e.waitForStep(6, 5000);
+   }
+
+   public void testReplacementCallbacks() {
+       DependencyManager m = getDM();
+       // helper class that ensures certain steps get executed in sequence
+       Ensure e = new Ensure();
+       // create a service provider and consumer
+       Component provider = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
+       Component provider2 = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface.class.getName()).build();
+       Component consumer = component(m).impl(new ServiceConsumer(e)).withService(ServiceInterface.class, srv->srv.cb("add", "remove")).build();
+       m.add(provider2);
+       m.add(consumer);
+       e.waitForStep(3, 15000);
+       m.add(provider);
+       m.remove(provider2);
+       e.step(4);
+       e.waitForStep(5, 15000);
+       m.remove(provider);
+       m.remove(consumer);
+       e.waitForStep(6, 15000);
+   }
+
+   static interface ServiceInterface {
+       public void invoke();
+   }
+
+   static class ServiceProvider implements ServiceInterface {
+       private final Ensure m_ensure;
+       public ServiceProvider(Ensure e) {
+           m_ensure = e;
+       }
+       public void invoke() {
+           m_ensure.step(5);
+       }
+   }
+
+   static class ServiceProvider2 implements ServiceInterface {
+       private final Ensure m_ensure;
+       public ServiceProvider2(Ensure e) {
+           m_ensure = e;
+       }
+       public void invoke() {
+           m_ensure.step(2);
+       }
+   }
+
+   static class ServiceConsumer implements Runnable {
+       private volatile ServiceInterface m_service;
+       private final Ensure m_ensure;
+
+       @SuppressWarnings("unused")
+       private void add(ServiceInterface service) { m_service = service; }
+       
+       @SuppressWarnings("unused")
+       private void remove(ServiceInterface service) { if (m_service == service) { m_service = null; }}
+       public ServiceConsumer(Ensure e) { m_ensure = e; }
+
+       public void start() {
+           Thread t = new Thread(this);
+           t.start();
+       }
+
+       public void run() {
+           m_ensure.step(1);
+           m_service.invoke();
+           m_ensure.step(3);
+           m_ensure.waitForStep(4, 15000);
+           m_service.invoke();
+       }
+
+       public void stop() {
+           m_ensure.step(6);
+       }
+   }
+}

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/compositefactory/Activator.java Sun Jan 17 23:38:55 2016
@@ -19,7 +19,7 @@
 package org.apache.felix.dependencymanager.lambda.samples.compositefactory;
 
 import static java.lang.System.out;
-import static org.apache.felix.dm.builder.lambda.Cb.ADD;
+import static org.apache.felix.dm.builder.lambda.Cb.*;
 
 import org.apache.felix.dm.builder.lambda.DependencyActivatorBase;
 import org.osgi.service.cm.ConfigurationAdmin;
@@ -52,6 +52,7 @@ public class Activator extends Dependenc
         // before creating the composition of classes.
         component(comp -> comp
             .factory(factory::create, factory::getComposition)
+            .cb(START, ProviderImpl::start) // only call start on ProviderImpl
             .withService(LogService.class, srv -> srv.cb(ADD, ProviderImpl::bind).cb(ADD, ProviderComposite1::bind))
             .withConfiguration(conf -> conf.pid(ProviderFactory.class).cbi(factory::updated)));
                 

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/Activator.java Sun Jan 17 23:38:55 2016
@@ -53,7 +53,7 @@ public class Activator extends Dependenc
         component(comp -> comp
             .impl(SpellChecker.class)
             .provides(SpellChecker.class, COMMAND_SCOPE, "dictionary", COMMAND_FUNCTION, new String[] {"spellcheck"}) 
-            .withService(DictionaryService.class, srv -> srv.required())
+            .withService(DictionaryService.class)
             .withService(LogService.class, srv -> srv.required(false)));
     }
 }

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java Sun Jan 17 23:38:55 2016
@@ -52,7 +52,7 @@ public class Activator extends Dependenc
         	.provides(FelixLinks.class)
             .withService(LogService.class, srv -> srv.cb(ADD, FelixLinksImpl::bind))
             .withFuture(futureLinks, future -> future.cb(FelixLinksImpl::setLinks)));
-            
+        
         // Define a component that just displays the links found from the Felix web site.
         // It depends on a log service and on the FelixLink service, which are both injected in class fields.
         component(comp -> comp

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/BundleDependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/BundleDependencyBuilder.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/BundleDependencyBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/BundleDependencyBuilder.java Sun Jan 17 23:38:55 2016
@@ -27,7 +27,6 @@ public interface BundleDependencyBuilder
 
     <T> BundleDependencyBuilder cb(Cb callbackType, CbTypeBundle<T> callback);
     <T> BundleDependencyBuilder cb(Cb callbackType, CbTypeComponentBundle<T> callback); 
-    
     BundleDependencyBuilder cbi(Cb callbackType, CbBundle callback);
     BundleDependencyBuilder cbi(Cb callbackType, CbComponentBundle callback);
 

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ComponentBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ComponentBuilder.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ComponentBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ComponentBuilder.java Sun Jan 17 23:38:55 2016
@@ -31,6 +31,23 @@ public interface ComponentBuilder<B exte
     <U> B impl(Class<U> implClass);   
 
     /**
+     * TODO
+     * 
+     * @param factory
+     * @param createMethod
+     * @return
+     */
+    B factory(Object factory, String createMethod);
+    
+    /**
+     * TODO
+     * 
+     * @param createMethod
+     * @return
+     */
+    B factory(java.lang.String createMethod);
+    
+    /**
      * Configures a factory that can be used to create this component implementation.
      * Example: "factory(ComponentImpl::new)", or "factory(() -> new ComponentImpl())".
      * 
@@ -132,6 +149,13 @@ public interface ComponentBuilder<B exte
 
     /**
      * Adds a required/autoconfig service dependency.
+     * @param service the service dependency filter
+     * @return this builder
+     */
+    B withService(Class<?> service, String filter);
+
+    /**
+     * Adds a required/autoconfig service dependency.
      * @param service the dependency that is required and that will be injected in any field with the same dependency type.
      * @return this builder
      */
@@ -166,6 +190,10 @@ public interface ComponentBuilder<B exte
      */
     <U> B withFuture(CompletableFuture<U> future, Consumer<FutureDependencyBuilder<U>> consumer);
 
+    
+    B cb(String init, String start, String stop, String destroy);
+    B cb(Object callbackInstance, String init, String start, String stop, String destroy);
+    
     <U> B cb(Cb callbackType, CbConsumer<U> callback);
     <U> B cb(Cb callbackType, CbBiConsumer<U, Component> callback);
     B cbi(Cb callbackType, Runnable callback);

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ConfigurationDependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ConfigurationDependencyBuilder.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ConfigurationDependencyBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ConfigurationDependencyBuilder.java Sun Jan 17 23:38:55 2016
@@ -27,6 +27,7 @@ public interface ConfigurationDependency
     ConfigurationDependencyBuilder pid(Class<?> pidClass);
     ConfigurationDependencyBuilder propagate();
     ConfigurationDependencyBuilder propagate(boolean propagate);
+    ConfigurationDependencyBuilder needsInstance(boolean needsInstance);
     
     ConfigurationDependencyBuilder cb(String updateMethod);
     ConfigurationDependencyBuilder cb(Object callbackInstance, String updateMethod);

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/Functions.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/Functions.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/Functions.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/Functions.java Sun Jan 17 23:38:55 2016
@@ -260,6 +260,16 @@ public class Functions {
     }
 
     @FunctionalInterface
+    public interface CbTypeComponentServiceService<T, S> extends SerializableLambda {
+        void accept(T instance, Component c, S old, S replace); 
+        
+        default CbTypeComponentServiceService<T, S> andThen(CbTypeComponentServiceService<? super T, S> after) {
+            Objects.requireNonNull(after);
+            return (T instance, Component c, S old, S replace) -> { accept(instance, c, old, replace); after.accept(instance, c, old, replace); };
+        }
+    }
+
+    @FunctionalInterface
     public interface CbTypeRefServiceRefService<T, S> extends SerializableLambda {
         void accept(T instance, ServiceReference<S> oldRef, S old, ServiceReference<S> replaceRef, S replace); 
         
@@ -270,6 +280,16 @@ public class Functions {
     }
     
     @FunctionalInterface
+    public interface CbTypeComponentRefServiceRefService<T, S> extends SerializableLambda {
+        void accept(T instance, Component c, ServiceReference<S> oldRef, S old, ServiceReference<S> replaceRef, S replace); 
+        
+        default CbTypeComponentRefServiceRefService<T, S> andThen(CbTypeComponentRefServiceRefService<? super T, S> after) {
+            Objects.requireNonNull(after);
+            return (T instance, Component c, ServiceReference<S> oldRef, S old, ServiceReference<S> replaceRef, S replace) -> { accept(instance, c, oldRef, old, replaceRef, replace); after.accept(instance, c, oldRef, old, replaceRef, replace); };
+        }
+    }
+    
+    @FunctionalInterface
     public interface CbTypeMapServiceMapService<T, S> extends SerializableLambda {
         void accept(T instance, Map<String, Object> oldProps, S old, Map<String, Object> replaceProps, S replace); 
         
@@ -300,6 +320,16 @@ public class Functions {
     }
 
     @FunctionalInterface
+    public interface CbComponentServiceService<S> extends SerializableLambda {
+        void accept(Component c, S old, S replace); 
+        
+        default CbComponentServiceService<S> andThen(CbComponentServiceService<S> after) {
+            Objects.requireNonNull(after);
+            return (Component c, S old, S replace) -> { accept(c, old, replace); after.accept(c, old, replace); };
+        }
+    }
+
+    @FunctionalInterface
     public interface CbRefServiceRefService<S> {
         void accept(ServiceReference<S> oldRef, S old, ServiceReference<S> replaceRef, S replace);
         
@@ -310,6 +340,16 @@ public class Functions {
     }
     
     @FunctionalInterface
+    public interface CbComponentRefServiceRefService<S> {
+        void accept(Component c, ServiceReference<S> oldRef, S old, ServiceReference<S> replaceRef, S replace);
+        
+        default CbComponentRefServiceRefService<S> andThen(CbComponentRefServiceRefService<S> after) {
+            Objects.requireNonNull(after);
+            return (Component c, ServiceReference<S> oldRef, S old, ServiceReference<S> replaceRef, S replace) -> { accept(c, oldRef, old, replaceRef, replace); after.accept(c, oldRef, old, replaceRef, replace); };
+        }
+    }
+    
+    @FunctionalInterface
     public interface CbMapServiceMapService<S> {
         void accept(Map<String, Object> oldProps, S old, Map<String, Object> replaceProps, S replace); 
         
@@ -320,6 +360,16 @@ public class Functions {
     }
     
     @FunctionalInterface
+    public interface CbComponentMapServiceMapService<S> {
+        void accept(Component c, Map<String, Object> oldProps, S old, Map<String, Object> replaceProps, S replace); 
+        
+        default CbComponentMapServiceMapService<S> andThen(CbComponentMapServiceMapService<S> after) {
+            Objects.requireNonNull(after);
+            return (Component c, Map<String, Object> oldProps, S old, Map<String, Object> replaceProps, S replace) -> { accept(c, oldProps, old, replaceProps, replace); after.accept(c, oldProps, old, replaceProps, replace); };
+        }
+    }
+    
+    @FunctionalInterface
     public interface CbDictServiceDictService<S> {
         void accept(Dictionary<String, Object> oldProps, S old, Dictionary<String, Object> replaceProps, S replace); 
         
@@ -329,6 +379,16 @@ public class Functions {
         }
     }
     
+    @FunctionalInterface
+    public interface CbComponentDictServiceDictService<S> {
+        void accept(Component c, Dictionary<String, Object> oldProps, S old, Dictionary<String, Object> replaceProps, S replace); 
+        
+        default CbComponentDictServiceDictService<S> andThen(CbComponentDictServiceDictService<S> after) {
+            Objects.requireNonNull(after);
+            return (Component c, Dictionary<String, Object> oldProps, S old, Dictionary<String, Object> replaceProps, S replace) -> { accept(c, oldProps, old, replaceProps, replace); after.accept(c, oldProps, old, replaceProps, replace); };
+        }
+    }
+    
     @FunctionalInterface
     public interface CbComponent {
         void accept(Component component);

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java Sun Jan 17 23:38:55 2016
@@ -39,7 +39,11 @@ import org.apache.felix.dm.builder.lambd
  * 
  * @param <F> the type of the CompletableFuture result.
  */
-public interface FutureDependencyBuilder<F> extends DependencyBuilder<Dependency> {    
+public interface FutureDependencyBuilder<F> extends DependencyBuilder<Dependency> { 
+    
+    FutureDependencyBuilder<F> cb(String callback);
+    FutureDependencyBuilder<F> cbi(Object callbackInstance, String callback);
+    
     /**
      * Sets the action to perform when the future task has completed. The action is one of the Component instance method that accepts the
      * result of the completed future.

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceCallbacksBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceCallbacksBuilder.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceCallbacksBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceCallbacksBuilder.java Sun Jan 17 23:38:55 2016
@@ -1,11 +1,15 @@
 package org.apache.felix.dm.builder.lambda;
 
 import org.apache.felix.dm.builder.lambda.Functions.CbComponent;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentDictServiceDictService;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentMapServiceMapService;
 import org.apache.felix.dm.builder.lambda.Functions.CbComponentRef;
 import org.apache.felix.dm.builder.lambda.Functions.CbComponentRefService;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentRefServiceRefService;
 import org.apache.felix.dm.builder.lambda.Functions.CbComponentService;
 import org.apache.felix.dm.builder.lambda.Functions.CbComponentServiceDict;
 import org.apache.felix.dm.builder.lambda.Functions.CbComponentServiceMap;
+import org.apache.felix.dm.builder.lambda.Functions.CbComponentServiceService;
 import org.apache.felix.dm.builder.lambda.Functions.CbDictServiceDictService;
 import org.apache.felix.dm.builder.lambda.Functions.CbMapServiceMapService;
 import org.apache.felix.dm.builder.lambda.Functions.CbRef;
@@ -18,9 +22,11 @@ import org.apache.felix.dm.builder.lambd
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponent;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentRef;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentRefService;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentRefServiceRefService;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentService;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentServiceDict;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentServiceMap;
+import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentServiceService;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeDictServiceDictService;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeMapServiceMapService;
 import org.apache.felix.dm.builder.lambda.Functions.CbTypeRef;
@@ -95,12 +101,17 @@ public interface ServiceCallbacksBuilder
     B cbi(Cb callbackType, CbComponentRefService<S> callback);
 
     <T> B sw(CbTypeServiceService<T, S> swap);
+    <T> B sw(CbTypeComponentServiceService<T, S> swap);
     <T> B sw(CbTypeRefServiceRefService<T, S> swap);
+    <T> B sw(CbTypeComponentRefServiceRefService<T, S> swap);
     <T> B sw(CbTypeMapServiceMapService<T, S> swap);
     <T> B sw(CbTypeDictServiceDictService<T, S> swap);
     B swi(CbServiceService<S> swap);
+    B swi(CbComponentServiceService<S> swap);
     B swi(CbRefServiceRefService<S> swap);
+    B swi(CbComponentRefServiceRefService<S> swap);
     B swi(CbMapServiceMapService<S> swap);
+    B swi(CbComponentMapServiceMapService<S> swap);
     B swi(CbDictServiceDictService<S> swap);
-    // TODO add more swap signatures with Component param.
+    B swi(CbComponentDictServiceDictService<S> swap);
 }

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/ServiceDependencyBuilder.java Sun Jan 17 23:38:55 2016
@@ -28,6 +28,12 @@ public interface ServiceDependencyBuilde
     ServiceDependencyBuilder<S> ref(ServiceReference<S> ref);
     
     /**
+     * Configures this dependency as optional. By default, a dependency is required.
+     * @return this builder
+     */
+    ServiceDependencyBuilder<S> optional();
+
+    /**
      * Configures this dependency as required. By default, a dependency is required.
 	 * @return this builder
      */

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/AdapterBase.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/AdapterBase.java?rev=1725147&r1=1725146&r2=1725147&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/AdapterBase.java (original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/AdapterBase.java Sun Jan 17 23:38:55 2016
@@ -38,6 +38,16 @@ public interface AdapterBase<B extends C
         return (B) this;
     }
 
+    default B factory(Object factory, String createMethod) {
+        andThenBuild(compBuilder -> compBuilder.factory(factory, createMethod));
+        return (B) this;
+    }
+
+    default B factory(String createMethod) {
+        andThenBuild(compBuilder -> compBuilder.factory(createMethod));
+        return (B) this;
+    }
+
     default <U> B factory(Supplier<U> create) {        
         andThenBuild(compBuilder -> compBuilder.factory(create));
         return (B) this;
@@ -153,6 +163,11 @@ public interface AdapterBase<B extends C
         return (B) this;
     }
     
+    default B withService(Class<?> service, String filter) {
+        andThenBuild(compBuilder -> compBuilder.withService(service, filter));
+        return (B) this;
+    }
+
     default B withService(Class<?> service, Class<?> ... services) {
         andThenBuild(compBuilder -> compBuilder.withService(service, services));
         return (B) this;
@@ -178,6 +193,16 @@ public interface AdapterBase<B extends C
         return (B) this;
     }
     
+    default B cb(String init, String start, String stop, String destroy) {
+        andThenBuild(compBuilder -> compBuilder.cb(init, start, stop, destroy));
+        return (B) this;
+    }
+    
+    default B cb(Object callbackInstance, String init, String start, String stop, String destroy) {
+        andThenBuild(compBuilder -> compBuilder.cb(callbackInstance, init, start, stop, destroy));
+        return (B) this;
+    }
+
     default <U> B cb(Cb callbackType, CbConsumer<U> callback) {
         andThenBuild(compBuilder -> compBuilder.cb(callbackType, callback));
         return (B) this;

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=1725147&r1=1725146&r2=1725147&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 Sun Jan 17 23:38:55 2016
@@ -1,5 +1,7 @@
 package org.apache.felix.dm.builder.lambda.impl;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 import java.util.stream.Stream;
@@ -49,6 +51,17 @@ public class CompletableFutureDependency
 	}
 
 	@Override
+    public FutureDependencyBuilder<F> cb(String callback) {
+	    return cbi(null, callback);
+	}
+	
+	@Override
+    public FutureDependencyBuilder<F> cbi(Object callbackInstance, String callback) {
+	    super.setCallbacks(callbackInstance, callback, null);
+	    return this;
+	}
+
+	@Override
 	public <T> FutureDependencyBuilder<F> cb(CbTypeFuture<T, ? super F> consumer) {
 	    return cb(consumer, false);
 	}
@@ -148,6 +161,11 @@ public class CompletableFutureDependency
         try {
             switch (type) {
             case ADDED:
+                if (m_add != null) {
+                    // Inject result by reflection on a method name
+                    injectByReflection(events[0].getEvent());
+                    return;
+                }
                 F result = events[0].getEvent();
                 if (m_accept2 != null) {
                     if (m_accept2Type != null) {
@@ -192,4 +210,32 @@ public class CompletableFutureDependency
 		    m_component.handleEvent(this, EventType.ADDED, new Event(result));
 		}
 	}
+    
+    /**
+     * Injects the completed fiture result in a method by reflection.
+     * We try to find a method which has in its signature a parameter that is compatible with the future result
+     * (including any interfaces the result may implements).
+     * 
+     * @param result the result of the completable future.
+     */
+    private void injectByReflection(Object result) {
+        List<Class<?>> types = new ArrayList<>();
+        Class<?> currentClazz = result.getClass();
+        
+        while (currentClazz != null && currentClazz != Object.class) {
+            types.add(currentClazz);
+            Stream.of(currentClazz.getInterfaces()).forEach(types::add);
+            currentClazz = currentClazz.getSuperclass();
+        }
+        
+        Class<?>[][] classes = new Class<?>[types.size() + 1][1];
+        Object[][] results = new Object[types.size() + 1][1];
+        for (int i = 0; i < types.size(); i ++) {
+            classes[i] = new Class<?>[] { types.get(i) };
+            results[i] = new Object[] { result };
+        }
+        classes[types.size()] = new Class<?>[0];
+        results[types.size()] = new Object[0];        
+        m_component.invokeCallbackMethod(getInstances(), m_add, classes, results);
+    }
 }



Mime
View raw message