Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectBaseTest.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/AspectBaseTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectBaseTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectBaseTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,362 @@
+/*
+ * 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.REM;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class AspectBaseTest extends TestBase {    
+
+       public void testSingleAspect() {
+           DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create a service provider and consumer
+        ServiceProvider p = new ServiceProvider(e, "a");
+        ServiceConsumer c = new ServiceConsumer(e);
+        
+        Component sp = component(m, comp -> comp
+            
.autoAdd(false).impl(p).provides(ServiceInterface.class).properties(name -> 
"a"));
+        
+        Component sc = component(m, comp -> comp
+            .autoAdd(false).impl(c).withService(ServiceInterface.class, srv -> 
srv.cb("add", "remove").autoConfig("m_service")));
+        
+        Component sa = aspect(m, ServiceInterface.class, asp -> 
asp.autoAdd(false).rank(20).impl(ServiceAspect.class));
+            
+        m.add(sc);
+        m.add(sp);
+        // after the provider was added, the consumer's add should have been 
invoked once
+        e.waitForStep(1, 2000);
+        Assert.assertEquals("a", c.invoke());
+        m.add(sa);
+        // after the aspect was added, the consumer should get and add for the 
aspect and a remove
+        // for the original service
+        e.waitForStep(3, 2000);
+        Assert.assertEquals("aa", c.invoke());
+        m.remove(sa);
+        // removing the aspect again should give a remove and add
+        e.waitForStep(5, 2000);
+        Assert.assertEquals("a", c.invoke());
+        m.remove(sp);
+        // finally removing the original service should give a remove
+        e.waitForStep(6, 2000);
+        m.remove(sc);
+        e.step(7);
+        clearComponents();
+    }
+    
+    public void testSingleAspectRef() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create a service provider and consumer
+        ServiceProvider p = new ServiceProvider(e, "a");
+        ServiceConsumer c = new ServiceConsumer(e);
+        
+        Component sp = component(m, comp -> comp
+            
.autoAdd(false).impl(p).provides(ServiceInterface.class).properties(name -> 
"a"));
+        
+        Component sc = component(m, comp -> comp
+            .autoAdd(false).impl(c).withService(ServiceInterface.class, srv -> 
srv.cbi(ADD, c::add).cbi(REM, c::remove).autoConfig("m_service")));
+        
+        Component sa = aspect(m, ServiceInterface.class, asp -> 
asp.autoAdd(false).rank(20).impl(ServiceAspect.class));
+        
+        m.add(sc);
+        m.add(sp);
+        // after the provider was added, the consumer's add should have been 
invoked once
+        e.waitForStep(1, 2000);
+        Assert.assertEquals("a", c.invoke());
+        m.add(sa);
+        // after the aspect was added, the consumer should get and add for the 
aspect and a remove
+        // for the original service
+        e.waitForStep(3, 2000);
+        Assert.assertEquals("aa", c.invoke());
+        m.remove(sa);
+        // removing the aspect again should give a remove and add
+        e.waitForStep(5, 2000);
+        Assert.assertEquals("a", c.invoke());
+        m.remove(sp);
+        // finally removing the original service should give a remove
+        e.waitForStep(6, 2000);
+        m.remove(sc);
+        e.step(7);
+        clearComponents();
+    }
+    
+    @SuppressWarnings("serial")
+    public void testSingleAspectThatAlreadyExisted() {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create a service provider and consumer
+        ServiceProvider p = new ServiceProvider(e, "a");
+        ServiceConsumer c = new ServiceConsumer(e);
+        Component sp = component(m, comp -> comp
+            
.autoAdd(false).impl(p).provides(ServiceInterface.class).properties(name -> 
"a"));
+            
+        Component sc = component(m, comp -> comp
+            .autoAdd(false).impl(c).withService(ServiceInterface.class, srv -> 
srv.cb("add", "remove").autoConfig("m_service")));
+        
+        Component sa = aspect(m, ServiceInterface.class, asp -> asp
+            .autoAdd(false).rank(20).impl(ServiceAspect.class));
+
+        // we first add the aspect
+        m.add(sa);
+        // then the service provider
+        m.add(sp);
+        // finally the consumer
+        m.add(sc);
+
+        Assert.assertEquals("aa", c.invoke());
+        
+        // now the consumer's added should be invoked once, as the aspect is 
already available and should
+        // directly hide the original service
+        e.waitForStep(1, 2000);
+        e.step(2);
+
+        m.remove(sa);
+        // after removing the aspect, the consumer should get the original 
service back, so
+        // remove and add will be invoked
+        e.waitForStep(4, 2000);
+        
+        Assert.assertEquals("a", c.invoke());
+        
+        m.remove(sp);
+        // after removing the original service, the consumer's remove should 
be called once
+        e.waitForStep(5, 2000);
+        
+        m.remove(sc);
+        e.step(6);
+    }
+
+    public void testSingleAspectThatAlreadyExistedRef() {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create a service provider and consumer
+        ServiceProvider p = new ServiceProvider(e, "a");
+        ServiceConsumer c = new ServiceConsumer(e);
+        
+        Component sp = component(m, comp -> comp
+            
.autoAdd(false).impl(p).provides(ServiceInterface.class).properties(name -> 
"a"));
+            
+        Component sc = component(m, comp -> comp
+            .autoAdd(false).impl(c).withService(ServiceInterface.class, srv -> 
srv.cbi(ADD, c::add).cbi(REM, c::remove).autoConfig("m_service")));
+        
+        Component sa = aspect(m, ServiceInterface.class, asp -> asp
+            .autoAdd(false).rank(20).impl(ServiceAspect.class));
+
+        // we first add the aspect
+        m.add(sa);
+        // then the service provider
+        m.add(sp);
+        // finally the consumer
+        m.add(sc);
+
+        Assert.assertEquals("aa", c.invoke());
+        
+        // now the consumer's added should be invoked once, as the aspect is 
already available and should
+        // directly hide the original service
+        e.waitForStep(1, 2000);
+        e.step(2);
+
+        m.remove(sa);
+        // after removing the aspect, the consumer should get the original 
service back, so
+        // remove and add will be invoked
+        e.waitForStep(4, 2000);
+        
+        Assert.assertEquals("a", c.invoke());
+        
+        m.remove(sp);
+        // after removing the original service, the consumer's remove should 
be called once
+        e.waitForStep(5, 2000);
+        
+        m.remove(sc);
+        e.step(6);
+    }
+
+    public void testMultipleAspects() {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create service providers and consumers
+        ServiceConsumer c = new ServiceConsumer(e);
+        Component sp = component(m, comp -> comp
+            .autoAdd(false).impl(new ServiceProvider(e, 
"a")).provides(ServiceInterface.class).properties(name -> "a"));
+        Component sp2 = component(m, comp -> comp
+            .autoAdd(false).impl(new ServiceProvider(e, 
"b")).provides(ServiceInterface.class).properties(name -> "b"));
+        Component sc = component(m, comp -> comp
+            .autoAdd(false).impl(c).withService(ServiceInterface.class, srv -> 
srv.cb("add", "remove")));
+
+        Component sa = aspect(m, ServiceInterface.class, asp -> 
asp.rank(20).impl(ServiceAspect.class));
+        Component sa2 = aspect(m, ServiceInterface.class, asp -> 
asp.rank(10).impl(ServiceAspect.class));
+
+        m.add(sp);
+        m.add(sp2);
+        m.add(sa);
+        m.add(sa2);
+        m.add(sc);
+        // the consumer will monitor progress, it should get it's add invoked 
twice, once for every
+        // (highest) aspect
+        e.waitForStep(2, 2000);
+        e.step(3);
+        
+        // now invoke all services the consumer collected
+        List<String> list = c.invokeAll();
+        // and make sure both of them are correctly invoked
+        Assert.assertTrue(list.size() == 2);
+        Assert.assertTrue(list.contains("aaa"));
+        Assert.assertTrue(list.contains("bbb"));
+        
+        m.remove(sc);
+        // removing the consumer now should get its removed method invoked 
twice
+        e.waitForStep(5, 2000);
+        e.step(6);
+        m.remove(sa2);
+        m.remove(sa);
+        m.remove(sp2);
+        m.remove(sp);
+        e.step(7);
+    }
+    
+    public void testMultipleAspectsRef() {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create service providers and consumers
+        ServiceConsumer c = new ServiceConsumer(e);
+        Component sp = component(m, comp -> comp
+            .autoAdd(false).impl(new ServiceProvider(e, 
"a")).provides(ServiceInterface.class).properties(name -> "a"));
+        Component sp2 = component(m, comp -> comp
+            .autoAdd(false).impl(new ServiceProvider(e, 
"b")).provides(ServiceInterface.class).properties(name -> "b"));
+        Component sc = component(m, comp -> comp
+            .autoAdd(false).impl(c).withService(ServiceInterface.class, srv -> 
srv.cbi(ADD, c::add).cbi(REM, c::remove)));
+
+        Component sa = aspect(m, ServiceInterface.class, asp -> 
asp.rank(20).impl(ServiceAspect.class));
+        Component sa2 = aspect(m, ServiceInterface.class, asp -> 
asp.rank(10).impl(ServiceAspect.class));
+
+        m.add(sp);
+        m.add(sp2);
+        m.add(sa);
+        m.add(sa2);
+        m.add(sc);
+        // the consumer will monitor progress, it should get it's add invoked 
twice, once for every
+        // (highest) aspect
+        e.waitForStep(2, 2000);
+        e.step(3);
+        
+        // now invoke all services the consumer collected
+        List<String> list = c.invokeAll();
+        // and make sure both of them are correctly invoked
+        Assert.assertTrue(list.size() == 2);
+        Assert.assertTrue(list.contains("aaa"));
+        Assert.assertTrue(list.contains("bbb"));
+        
+        m.remove(sc);
+        // removing the consumer now should get its removed method invoked 
twice
+        e.waitForStep(5, 2000);
+        e.step(6);
+        m.remove(sa2);
+        m.remove(sa);
+        m.remove(sp2);
+        m.remove(sp);
+        e.step(7);
+    }
+    
+    public static interface ServiceInterface {
+        public String invoke(String input);
+    }
+    
+    public static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        private final String m_name;
+        public ServiceProvider(Ensure e, String name) {
+            m_ensure = e;
+            m_name = name;
+        }
+        public String invoke(String input) {
+            return input + m_name;
+        }
+    }
+    
+    public static class ServiceAspect implements ServiceInterface {
+        private volatile ServiceInterface m_originalService;
+        private volatile ServiceRegistration m_registration;
+        
+        public String invoke(String input) {
+            String result = m_originalService.invoke(input);
+            String property = (String) 
m_registration.getReference().getProperty("name");
+            return result + property;
+        }
+    }
+    
+    public static class ServiceConsumer {
+        private final Ensure m_ensure;
+        private volatile ServiceInterface m_service;
+        private List<ServiceInterface> m_services = new 
ArrayList<ServiceInterface>();
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void add(ServiceReference<ServiceInterface> ref, 
ServiceInterface si) {
+            System.out.println("add: " + ServiceUtil.toString(ref));
+            m_services.add(si);
+            m_ensure.step();
+        }
+        
+        public void remove(ServiceReference<ServiceInterface> ref, 
ServiceInterface si) {
+            System.out.println("rem: " + ServiceUtil.toString(ref));
+            m_services.remove(si);
+            m_ensure.step();
+        }
+        
+        public String invoke() {
+            return m_service.invoke("");
+        }
+        
+        public List<String> invokeAll() {
+            List<String> results = new ArrayList<String>();
+            for (ServiceInterface si : m_services) {
+                results.add(si.invoke(""));
+            }
+            return results;
+        }
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectChainTest.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/AspectChainTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectChainTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectChainTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,113 @@
+/*
+ * 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.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class AspectChainTest extends TestBase {
+
+       public void testBuildAspectChain() {
+           DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Component sp = component(m, c -> c.impl(new 
ServiceProvider(e)).provides(ServiceInterface.class));
+        Component sc = component(m, c -> c.impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class));
+        Component sa2 = aspect(m, ServiceInterface.class, a -> 
a.rank(20).impl(new ServiceAspect(e, 3)));
+        Component sa3 = aspect(m, ServiceInterface.class, a -> 
a.rank(30).impl(new ServiceAspect(e, 2)));
+        Component sa1 = aspect(m, ServiceInterface.class, a -> 
a.rank(10).impl(new ServiceAspect(e, 4)));
+        m.add(sc);
+
+        m.add(sp);
+        m.add(sa2);
+        m.add(sa3);
+        m.add(sa1);
+        e.step();
+        e.waitForStep(5,  5000);
+        
+        m.remove(sa3);
+        m.remove(sa2);
+        m.remove(sa1);
+        m.remove(sp);
+        
+        m.remove(sc);
+    }
+    
+    static interface ServiceInterface {
+        public void invoke(Runnable run);
+    }
+    
+    static class ServiceProvider implements ServiceInterface {
+        @SuppressWarnings("unused")
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke(Runnable run) {
+            run.run();
+        }
+    }
+    
+    static class ServiceAspect implements ServiceInterface {
+        private final Ensure m_ensure;
+        private volatile ServiceInterface m_parentService;
+        private final int m_step;
+        
+        public ServiceAspect(Ensure e, int step) {
+            m_ensure = e;
+            m_step = step;
+        }
+        public void start() {
+        }
+        
+        public void invoke(Runnable run) {
+            m_ensure.step(m_step);
+            m_parentService.invoke(run);
+        }
+        
+        public void stop() {
+        }
+    }
+
+    static class ServiceConsumer implements Runnable {
+        private volatile ServiceInterface m_service;
+        private final Ensure m_ensure;
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            Thread t = new Thread(this);
+            t.start();
+        }
+        
+        public void run() {
+            m_ensure.waitForStep(1, 2000);
+            m_service.invoke(Ensure.createRunnableStep(m_ensure, 5));
+        }
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectDynamicsTest.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/AspectDynamicsTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectDynamicsTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectDynamicsTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,253 @@
+/*
+ * 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.DependencyActivatorBase.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class AspectDynamicsTest extends TestBase {
+
+       public void testDynamicallyAddAndRemoveAspect() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        Ensure aspectStopEnsure = new Ensure();
+        // create a service provider and consumer
+        Component provider = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component provider2 = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider2(e)).provides(ServiceInterface2.class.getName()));
+        Component consumer = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class, s->s.cb("add", null, 
null, "swap")));
+        Component aspect = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(1).impl(new ServiceAspect(e, aspectStopEnsure)));
+        
+        m.add(consumer);
+        m.add(provider);
+        // the consumer should invoke the provider here, and when done, arrive 
at step 3
+        // finally wait for step 6 before continuing
+        e.waitForStep(3, 15000);
+        
+        m.add(aspect);
+        // after adding the aspect, we wait for its init to be invoked, 
arriving at
+        // step 4 after an instance bound dependency was added (on a service 
provided by
+        // provider 2)
+        e.waitForStep(4, 15000);
+        
+        m.add(provider2);
+        
+        // after adding provider 2, we should now see the client being 
swapped, so
+        // we wait for step 5 to happen
+        e.waitForStep(5, 15000);
+        
+        // now we continue with step 6, which will trigger the next part of 
the consumer's
+        // run method to be executed
+        e.step(6);
+        
+        // invoking step 7, 8 and 9 when invoking the aspect which in turn 
invokes the
+        // dependency and the original service, so we wait for that to finish 
here, which
+        // is after step 10 has been reached (the client will now wait for 
step 12)
+        e.waitForStep(10, 15000);
+        
+        m.remove(aspect);
+        aspectStopEnsure.waitForStep(1, 15000);
+        // removing the aspect should trigger step 11 (in the swap method of 
the consumer)
+        e.waitForStep(11, 15000);
+        
+        // step 12 triggers the client to continue
+        e.step(12);
+        
+        // wait for step 13, the final invocation of the provided service 
(without aspect)
+        e.waitForStep(13, 15000);
+        
+        // clean up
+        m.remove(provider2);
+        m.remove(provider);
+        m.remove(consumer);
+        e.waitForStep(16, 15000);
+        m.clear();
+    }
+    
+    public void testDynamicallyAddAndRemoveAspectRef() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        Ensure aspectStopEnsure = new Ensure();
+        // create a service provider and consumer
+        Component provider = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component provider2 = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider2(e)).provides(ServiceInterface2.class.getName()));
+        Component consumer = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class, s->s.cb(ADD, 
ServiceConsumer::add).sw(ServiceConsumer::swap)));
+        Component aspect = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(1).impl(new ServiceAspect(e, aspectStopEnsure)));
+        
+        m.add(consumer);
+        m.add(provider);
+        // the consumer should invoke the provider here, and when done, arrive 
at step 3
+        // finally wait for step 6 before continuing
+        e.waitForStep(3, 15000);
+        
+        m.add(aspect);
+        // after adding the aspect, we wait for its init to be invoked, 
arriving at
+        // step 4 after an instance bound dependency was added (on a service 
provided by
+        // provider 2)
+        e.waitForStep(4, 15000);
+        
+        m.add(provider2);
+        
+        // after adding provider 2, we should now see the client being 
swapped, so
+        // we wait for step 5 to happen
+        e.waitForStep(5, 15000);
+        
+        // now we continue with step 6, which will trigger the next part of 
the consumer's
+        // run method to be executed
+        e.step(6);
+        
+        // invoking step 7, 8 and 9 when invoking the aspect which in turn 
invokes the
+        // dependency and the original service, so we wait for that to finish 
here, which
+        // is after step 10 has been reached (the client will now wait for 
step 12)
+        e.waitForStep(10, 15000);
+        
+        m.remove(aspect);
+        aspectStopEnsure.waitForStep(1, 15000);
+        // removing the aspect should trigger step 11 (in the swap method of 
the consumer)
+        e.waitForStep(11, 15000);
+        
+        // step 12 triggers the client to continue
+        e.step(12);
+        
+        // wait for step 13, the final invocation of the provided service 
(without aspect)
+        e.waitForStep(13, 15000);
+        
+        // clean up
+        m.remove(provider2);
+        m.remove(provider);
+        m.remove(consumer);
+        e.waitForStep(16, 15000);
+        m.clear();
+    }
+    
+    static interface ServiceInterface {
+        public void invoke(Runnable run);
+    }
+    
+    static interface ServiceInterface2 {
+        public void invoke();
+    }
+    
+    static class ServiceProvider2 implements ServiceInterface2 {
+        private final Ensure m_ensure;
+
+        public ServiceProvider2(Ensure ensure) {
+            m_ensure = ensure;
+        }
+
+        public void invoke() {
+            m_ensure.step(9);
+        }
+        public void stop() {
+            m_ensure.step();
+        }
+    }
+
+    static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke(Runnable run) {
+            run.run();
+        }
+        public void stop() {
+            m_ensure.step();
+        }
+    }
+    
+    static class ServiceAspect implements ServiceInterface {
+        private final Ensure m_ensure;
+        private volatile ServiceInterface m_originalService;
+        private volatile ServiceInterface2 m_injectedService;
+        private volatile Component m_service;
+        private volatile DependencyManager m_manager;
+        private final Ensure m_stopEnsure;
+        
+        public ServiceAspect(Ensure e, Ensure stopEnsure) {
+            m_ensure = e;
+            m_stopEnsure = stopEnsure;
+        }
+        public void init() {
+            m_service.add(m_manager.createServiceDependency()
+                .setService(ServiceInterface2.class)
+                .setRequired(true)
+            );
+            m_ensure.step(4);
+        }
+
+        public void invoke(Runnable run) {
+            m_ensure.step(7);
+            m_originalService.invoke(run);
+            m_injectedService.invoke();
+        }
+        
+        public void stop() {
+            m_stopEnsure.step(1);
+        }
+    }
+
+    static class ServiceConsumer implements Runnable {
+        private volatile ServiceInterface m_service;
+        private final Ensure m_ensure;
+        private final Ensure.Steps m_swapSteps = new Ensure.Steps(5, 11);
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        void add(ServiceInterface service) {
+            m_service = service;
+        }
+        
+        void swap(ServiceInterface oldService, ServiceInterface newService) {
+            System.out.println("swap: old=" + oldService + ", new=" + 
newService);
+            m_ensure.steps(m_swapSteps);
+            m_service = newService;
+        }
+        
+        public void init() {
+            Thread t = new Thread(this);
+            t.start();
+        }
+        
+        public void run() {
+            m_ensure.step(1);
+            m_service.invoke(Ensure.createRunnableStep(m_ensure, 2));
+            m_ensure.step(3);
+            m_ensure.waitForStep(6, 15000);
+            m_service.invoke(Ensure.createRunnableStep(m_ensure, 8));
+            m_ensure.step(10);
+            m_ensure.waitForStep(12, 15000);
+            m_service.invoke(Ensure.createRunnableStep(m_ensure, 13));
+        }
+        
+        public void stop() {
+            m_ensure.step();
+        }
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectServiceDependencyTest.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/AspectServiceDependencyTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectServiceDependencyTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectServiceDependencyTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,120 @@
+/*
+ * 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.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class AspectServiceDependencyTest extends TestBase {
+    public void testServiceRegistrationAndConsumption() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Component sp = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component sc = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class, s->s.cb("add", 
"remove")));
+        Component asp = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(100).impl(ServiceProviderAspect.class));
+                       
+        m.add(sp);
+        m.add(sc);
+        m.add(asp);
+        m.remove(asp); 
+        m.remove(sc);
+        m.remove(sp);
+        
+        // ensure we executed all steps inside the component instance
+        e.step(8);
+    }
+    
+    static interface ServiceInterface {
+        public void invoke(String caller);
+    }
+
+    static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke(String caller) {
+               if (caller.equals("consumer.init")) {
+                       m_ensure.step(3);
+               } else if (caller.equals("aspect.consumer.add")) {
+                       m_ensure.step(5);
+               }
+        }
+    }
+    
+    static class ServiceProviderAspect implements ServiceInterface {
+       private volatile ServiceInterface m_service;
+       
+       public ServiceProviderAspect() {
+               }
+
+               @Override
+               public void invoke(String caller) {
+                       m_service.invoke("aspect." + caller);
+               }
+    }
+
+    static class ServiceConsumer {
+        private volatile ServiceInterface m_service;
+        private final Ensure m_ensure;
+        private int addCount = 0;
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            m_ensure.step(2);
+            m_service.invoke("consumer.init");
+        }
+        
+        public void destroy() {
+            m_ensure.step(7);
+        }
+        
+        public void add(ServiceInterface service) {
+               m_service = service;
+               switch (addCount) {
+                       case 0: m_ensure.step(1);
+                                       break;
+                       case 1: m_ensure.step(4);
+                                       // aspect had been added
+                                       m_service.invoke("consumer.add");
+                                       break;
+                       case 2: m_ensure.step(6);
+                                       break;
+                       default:
+               }
+               addCount ++;
+        }
+        public void remove(ServiceInterface service) {
+               m_service = null;
+        }    
+    }
+
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectServiceDependencyWithSwapCallbackTest.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/AspectServiceDependencyWithSwapCallbackTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectServiceDependencyWithSwapCallbackTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectServiceDependencyWithSwapCallbackTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,143 @@
+/*
+ * 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.REM;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class AspectServiceDependencyWithSwapCallbackTest extends TestBase {
+    public void testServiceRegistrationAndConsumption() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Component sp = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class));
+        Component sc = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class, s->s.cb("add", null, 
"remove", "swap")));
+        Component asp = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(100).impl(ServiceProviderAspect.class));
+        m.add(sp);
+        m.add(sc);
+        m.add(asp);
+        m.remove(asp); 
+        m.remove(sc);
+        m.remove(sp);
+        
+        // ensure we executed all steps inside the component instance
+        e.step(7);
+    }
+    
+    public void testServiceRegistrationAndConsumptionRef() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        ServiceConsumer scimpl = new ServiceConsumer(e);
+        Component sp = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class));
+        Component sc = component(m, 
c->c.autoAdd(false).impl(scimpl).withService(ServiceInterface.class, 
s->s.cbi(ADD, scimpl::add).cbi(REM, scimpl::remove).swi(scimpl::swap)));
+        Component asp = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(100).impl(ServiceProviderAspect.class));
+        m.add(sp);
+        m.add(sc);
+        m.add(asp);
+        m.remove(asp); 
+        m.remove(sc);
+        m.remove(sp);
+        
+        // ensure we executed all steps inside the component instance
+        e.step(7);
+    }
+
+    static interface ServiceInterface {
+        public void invoke(String caller);
+    }
+
+    static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke(String caller) {
+               if (caller.equals("consumer.init")) {
+                       m_ensure.step(3);
+               } else if (caller.equals("aspect.consumer.add")) {
+                       m_ensure.step(5);
+               }
+        }
+    }
+    
+    static class ServiceProviderAspect implements ServiceInterface {
+       private volatile ServiceInterface m_service;
+       
+       public ServiceProviderAspect() {
+               }
+
+               @Override
+               public void invoke(String caller) {
+                       m_service.invoke("aspect." + caller);
+               }
+    }
+
+    static class ServiceConsumer {
+        private volatile ServiceInterface m_service;
+        private final Ensure m_ensure;
+        private int swapCount = 0;
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            m_ensure.step(2);
+            m_service.invoke("consumer.init");
+        }
+        
+        public void destroy() {
+            m_ensure.step(6);
+        }
+        
+        public void add(ServiceInterface service) {
+               m_service = service;
+               m_ensure.step(1);
+        }
+        
+        public void remove(ServiceInterface service) {
+               m_service = null;
+        }
+        
+        public void swap(ServiceInterface previous, ServiceInterface current) {
+               switch (swapCount) {
+                       case 0: m_ensure.step(4);
+                                       break;
+                       case 1: m_ensure.step(5);
+                                       break;
+                       default:
+               }
+               m_service = current;
+               swapCount ++;
+        }
+    }
+
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWhiteboardTest.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/AspectWhiteboardTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWhiteboardTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWhiteboardTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,279 @@
+/*
+ * 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.REM;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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;
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+@SuppressWarnings({"rawtypes", "unchecked", "unused"})
+public class AspectWhiteboardTest extends TestBase {
+
+       public void testWhiteboardConsumer() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create service providers and consumer
+        Component sp1 = component(m, s->s.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component sp2 = component(m, s->s.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        ServiceConsumer sci = new ServiceConsumer(e);
+        Component sc = component(m, 
s->s.autoAdd(false).impl(sci).withService(ServiceInterface.class, 
srv->srv.required(false).cb("add", "remove")));
+        Component sa2 = aspect(m, ServiceInterface.class, 
a->a.rank(20).autoAdd(false).impl(new ServiceAspect(e, 3)));
+        Component sa1 = aspect(m, ServiceInterface.class, 
a->a.rank(10).autoAdd(false).impl(new ServiceAspect(e, 4)));
+        
+        // start with a service consumer
+        System.out.println("Adding consumer");
+        m.add(sc);
+        
+        // then add two providers, so the consumer will see two services
+        System.out.println("Adding 2 providers");
+        m.add(sp1);
+        m.add(sp2);
+        
+        // make sure consumer sees both services
+        Assert.assertEquals(2, sci.services());
+        
+        // add an aspect with ranking 20
+        System.out.println("Adding aspect with rank 20");
+        m.add(sa2);
+        
+        // make sure the consumer sees the two new aspects and no longer sees 
the two original services
+        Assert.assertEquals(2, sci.services());
+        Assert.assertEquals(20, sci.highestRanking());
+        Assert.assertEquals(20, sci.lowestRanking());
+        
+        // add an aspect with ranking 10
+        System.out.println("Adding aspect with rank 10");
+        m.add(sa1);
+        
+        // make sure the consumer still sees the two aspects with ranking 20
+        Assert.assertEquals(2, sci.services());
+        Assert.assertEquals(20, sci.highestRanking());
+        Assert.assertEquals(20, sci.lowestRanking());
+        
+        // remove the aspect with ranking 20
+        System.out.println("Removing aspect with rank 20");
+        m.remove(sa2);
+        
+        // make sure the consumer now sees the aspects with ranking 10
+        Assert.assertEquals(2, sci.services());
+        Assert.assertEquals(10, sci.highestRanking());
+        Assert.assertEquals(10, sci.lowestRanking());
+        
+        // remove one of the original services
+        System.out.println("Removing 1 service");
+        m.remove(sp1);
+        
+        // make sure the aspect of that service goes away
+        Assert.assertEquals(1, sci.services());
+        Assert.assertEquals(10, sci.highestRanking());
+        Assert.assertEquals(10, sci.lowestRanking());
+        
+        // remove the aspect with ranking 10
+        System.out.println("Removing aspect with rank 10");
+        m.remove(sa1);
+        
+        // make sure only the original service remains
+        Assert.assertEquals(1, sci.services());
+        Assert.assertEquals(0, sci.highestRanking());
+        Assert.assertEquals(0, sci.lowestRanking());
+
+        System.out.println("Done with test");
+
+        // end of test
+        m.remove(sa2);
+        m.remove(sp2);
+        m.remove(sc);
+    }
+    
+    public void testWhiteboardConsumerRef() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create service providers and consumer
+        Component sp1 = component(m, s->s.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component sp2 = component(m, s->s.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        ServiceConsumer sci = new ServiceConsumer(e);
+        Component sc = component(m, 
s->s.autoAdd(false).impl(sci).withService(ServiceInterface.class, 
srv->srv.required(false).cbi(ADD, sci::add).cbi(REM, sci::remove)));
+        Component sa2 = aspect(m, ServiceInterface.class, 
a->a.rank(20).autoAdd(false).impl(new ServiceAspect(e, 3)));
+        Component sa1 = aspect(m, ServiceInterface.class, 
a->a.rank(10).autoAdd(false).impl(new ServiceAspect(e, 4)));
+        
+        // start with a service consumer
+        System.out.println("Adding consumer");
+        m.add(sc);
+        
+        // then add two providers, so the consumer will see two services
+        System.out.println("Adding 2 providers");
+        m.add(sp1);
+        m.add(sp2);
+        
+        // make sure consumer sees both services
+        Assert.assertEquals(2, sci.services());
+        
+        // add an aspect with ranking 20
+        System.out.println("Adding aspect with rank 20");
+        m.add(sa2);
+        
+        // make sure the consumer sees the two new aspects and no longer sees 
the two original services
+        Assert.assertEquals(2, sci.services());
+        Assert.assertEquals(20, sci.highestRanking());
+        Assert.assertEquals(20, sci.lowestRanking());
+        
+        // add an aspect with ranking 10
+        System.out.println("Adding aspect with rank 10");
+        m.add(sa1);
+        
+        // make sure the consumer still sees the two aspects with ranking 20
+        Assert.assertEquals(2, sci.services());
+        Assert.assertEquals(20, sci.highestRanking());
+        Assert.assertEquals(20, sci.lowestRanking());
+        
+        // remove the aspect with ranking 20
+        System.out.println("Removing aspect with rank 20");
+        m.remove(sa2);
+        
+        // make sure the consumer now sees the aspects with ranking 10
+        Assert.assertEquals(2, sci.services());
+        Assert.assertEquals(10, sci.highestRanking());
+        Assert.assertEquals(10, sci.lowestRanking());
+        
+        // remove one of the original services
+        System.out.println("Removing 1 service");
+        m.remove(sp1);
+        
+        // make sure the aspect of that service goes away
+        Assert.assertEquals(1, sci.services());
+        Assert.assertEquals(10, sci.highestRanking());
+        Assert.assertEquals(10, sci.lowestRanking());
+        
+        // remove the aspect with ranking 10
+        System.out.println("Removing aspect with rank 10");
+        m.remove(sa1);
+        
+        // make sure only the original service remains
+        Assert.assertEquals(1, sci.services());
+        Assert.assertEquals(0, sci.highestRanking());
+        Assert.assertEquals(0, sci.lowestRanking());
+
+        System.out.println("Done with test");
+
+        // end of test
+        m.remove(sa2);
+        m.remove(sp2);
+        m.remove(sc);
+    }
+    
+    static interface ServiceInterface {
+        public void invoke(Runnable run);
+    }
+    
+    static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke(Runnable run) {
+            run.run();
+        }
+    }
+    
+    static class ServiceAspect implements ServiceInterface {
+        private final Ensure m_ensure;
+        private volatile ServiceInterface m_parentService;
+        private final int m_step;
+        
+        public ServiceAspect(Ensure e, int step) {
+            m_ensure = e;
+            m_step = step;
+        }
+        public void start() {
+        }
+        
+        public void invoke(Runnable run) {
+            m_ensure.step(m_step);
+            m_parentService.invoke(run);
+        }
+        
+        public void stop() {
+        }
+    }
+
+    static class ServiceConsumer implements Runnable {
+        private List m_services = new ArrayList();
+        private final Ensure m_ensure;
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            Thread t = new Thread(this);
+            t.start();
+        }
+        
+        public void run() {
+        }
+        
+        public int services() {
+            return m_services.size();
+        }
+        
+        public int highestRanking() {
+            int ranking = Integer.MIN_VALUE;
+            for (int i = 0; i < m_services.size(); i++) {
+                ServiceReference ref = (ServiceReference) m_services.get(i);
+                Integer r = (Integer) 
ref.getProperty(Constants.SERVICE_RANKING);
+                int rank = r == null ? 0 : r.intValue();
+                ranking = Math.max(ranking, rank);
+            }
+            return ranking;
+        }
+        public int lowestRanking() {
+            int ranking = Integer.MAX_VALUE;
+            for (int i = 0; i < m_services.size(); i++) {
+                ServiceReference ref = (ServiceReference) m_services.get(i);
+                Integer r = (Integer) 
ref.getProperty(Constants.SERVICE_RANKING);
+                int rank = r == null ? 0 : r.intValue();
+                ranking = Math.min(ranking, rank);
+            }
+            return ranking;
+        }
+        
+        public void add(ServiceReference ref, ServiceInterface svc) {
+            System.out.println("Added: " + ServiceUtil.toString(ref));
+            m_services.add(ref);
+        }
+        public void remove(ServiceReference ref, ServiceInterface svc) {
+            System.out.println("Removed: " + ServiceUtil.toString(ref));
+            m_services.remove(ref);
+        }
+    }
+}

Added: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithCallbacksServiceDependencyTest.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/AspectWithCallbacksServiceDependencyTest.java?rev=1724333&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithCallbacksServiceDependencyTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/AspectWithCallbacksServiceDependencyTest.java
 Tue Jan 12 22:45:36 2016
@@ -0,0 +1,199 @@
+/*
+ * 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.REM;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.aspect;
+import static 
org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+
+/**
+ * @author <a href="mailto:[email protected]";>Felix Project Team</a>
+ */
+public class AspectWithCallbacksServiceDependencyTest extends TestBase {
+    public void testServiceRegistrationAndConsumption() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Component sp = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component sc = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class, s->s.cb("add", 
"remove")));
+        Component asp = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(100).cb("add", null, "remove", 
"swap").impl(ServiceProviderAspect.class));
+                       
+        m.add(sp);
+        m.add(sc);
+        m.add(asp);
+        m.remove(asp); 
+        m.remove(sc);
+        m.remove(sp);
+        
+        // ensure we executed all steps inside the component instance
+        e.step(8);
+    }
+    
+    public void testServiceRegistrationAndConsumptionRef() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Component sp = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class.getName()));
+        Component sc = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e))
+            .withService(ServiceInterface.class, s->s.cb(ADD, 
ServiceConsumer::add).cb(REM, ServiceConsumer::remove)));
+        Component asp = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).impl(ServiceProviderAspect.class).rank(100)
+            .cb(ADD, ServiceProviderAspect::add).cb(REM, 
ServiceProviderAspect::remove).sw(ServiceProviderAspect::swap));
+                
+        m.add(sp);
+        m.add(sc);
+        m.add(asp);
+        m.remove(asp); 
+        m.remove(sc);
+        m.remove(sp);
+        
+        // ensure we executed all steps inside the component instance
+        e.step(8);
+    }
+    
+    public void 
testServiceRegistrationAndConsumptionWithAspectCallbackInstance() {
+        DependencyManager m = getDM();
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Component sp = component(m, c->c.autoAdd(false).impl(new 
ServiceProvider(e)).provides(ServiceInterface.class));
+        Component sc = component(m, c->c.autoAdd(false).impl(new 
ServiceConsumer(e)).withService(ServiceInterface.class, s->s.cb("add", 
"remove")));
+                
+        ServiceProviderAspect providerAspect = new ServiceProviderAspect();
+        ServiceProviderAspectCallbackInstance aspectCb = new 
ServiceProviderAspectCallbackInstance(providerAspect);
+        Component asp = aspect(m, ServiceInterface.class, 
a->a.autoAdd(false).rank(100).impl(providerAspect)
+            .cbi(ADD, 
aspectCb::add).cbi(REM,aspectCb::remove).swi(aspectCb::swap));
+        m.add(sp);
+        m.add(sc);
+        m.add(asp);
+        m.remove(asp); 
+        m.remove(sc);
+        m.remove(sp);
+        
+        // ensure we executed all steps inside the component instance
+        e.step(8);
+    }
+    
+   static interface ServiceInterface {
+        public void invoke(String caller);
+    }
+
+    static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        public ServiceProvider(Ensure e) {
+            m_ensure = e;
+        }
+        public void invoke(String caller) {
+               if (caller.equals("consumer.init")) {
+                       m_ensure.step(3);
+               } else if (caller.equals("aspect.consumer.add")) {
+                       m_ensure.step(5);
+               }
+        }
+    }
+    
+    public static class ServiceProviderAspectCallbackInstance {
+        private final ServiceProviderAspect m_aspect;
+        
+        ServiceProviderAspectCallbackInstance(ServiceProviderAspect aspect) {
+            m_aspect = aspect;
+        }
+        
+        public void add(ServiceInterface service) {
+            m_aspect.add(service);
+        }
+        
+        public void remove(ServiceInterface service) {
+            m_aspect.remove(service);
+        }
+        
+        public void swap(ServiceInterface previous, ServiceInterface current) {
+            m_aspect.swap(previous, current);
+        }
+    }
+
+    static class ServiceProviderAspect implements ServiceInterface {
+       private volatile ServiceInterface m_service;
+       
+       public ServiceProviderAspect() {
+               }
+
+               @Override
+               public void invoke(String caller) {
+                       m_service.invoke("aspect." + caller);
+               }
+               
+               public void add(ServiceInterface service) {
+                       m_service = service;
+               }
+               
+               public void remove(ServiceInterface service) {
+                       m_service = null;
+               }
+               
+               public void swap(ServiceInterface previous, ServiceInterface 
current) {
+                       m_service = current;
+               }
+    }
+
+    static class ServiceConsumer {
+        private volatile ServiceInterface m_service;
+        private final Ensure m_ensure;
+        private int addCount = 0;
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void init() {
+            m_ensure.step(2);
+            m_service.invoke("consumer.init");
+        }
+        
+        public void destroy() {
+            m_ensure.step(7);
+        }
+        
+        public void add(ServiceInterface service) {
+               m_service = service;
+               switch (addCount) {
+                       case 0: m_ensure.step(1);
+                                       break;
+                       case 1: m_ensure.step(4);
+                                       // aspect had been added
+                                       m_service.invoke("consumer.add");
+                                       break;
+                       case 2: m_ensure.step(6);
+                                       break;
+                       default:
+               }
+               addCount ++;
+        }
+        public void remove(ServiceInterface service) {
+               m_service = null;
+        }    
+    }
+
+}


Reply via email to