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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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);
+ }
}