FELIX-4689: Create a more fluent syntax for the dependency manager builder.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1727869 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Activator.java
new file mode 100644
index 0000000..2aab3bc
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Activator.java
@@ -0,0 +1,63 @@
+/*
+ * 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.lambda.samples.compositefactory;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.lambda.DependencyManagerActivator;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.log.LogService;
+
+/**
+ * Creates a "Provider" service. The implementation for this service (ProviderImpl) is
+ * created using a factory class (ProviderFactory) that also creates some other helper classes
+ * (ProviderComposite1 and ProviderComposite2) that are internally used by ProviderImpl.
+ *
+ * The ProviderFactory is also injected with a Configuration that can be used by the Factory
+ * when creating the ProviderImpl, ProviderComposite1, and ProviderComposite2 classes.
+ *
+ * The LogService in only injected to the ProviderImpl and the ProviderComposite1 classes.
+ * Both composites are called in their "start" callbacks, when all required dependencies are available.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyManagerActivator {
+ @Override
+ public void activate() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // Create the Factory used to instantiate ProvuderImpl, ProviderComposite1 and ProviderComposite2
+ ProviderFactory factory = new ProviderFactory();
+
+ // Define the component which implementation is instantiated by the ProviderFactory.
+ // a LogService is injected in the ProviderImpl, as well as to the ProviderComposite1 class.
+ // And a configuration is injected directly to the ProviderFactory so it can use some configurations
+ // before creating the composition of classes.
+ component(comp -> comp
+ .factory(factory::create, factory::getComposition)
+ .start(ProviderImpl::start) // only call start on ProviderImpl
+ .withSrv(LogService.class, srv -> srv.cb(ProviderImpl::bind).cb(ProviderComposite1::bind))
+ .withCnf(conf -> conf.pid(ProviderFactory.class).cbi(factory::updated)));
+
+ // Creates a configuration with pid name = "org.apache.felix.dependencymanager.lambda.samples.compositefactory.ProviderFactory"
+ component(comp -> comp
+ .impl(Configurator.class)
+ .withSrv(ConfigurationAdmin.class));
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Configurator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Configurator.java
new file mode 100644
index 0000000..b030616
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Configurator.java
@@ -0,0 +1,20 @@
+package org.apache.felix.dm.lambda.samples.compositefactory;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class Configurator {
+ volatile ConfigurationAdmin m_cm; // injected by reflection.
+
+ void start() throws IOException {
+ // Configure the ServiceConsumer component
+ Configuration c = m_cm.getConfiguration(ProviderFactory.class.getName(), null);
+ Dictionary<String, Object> props = new Hashtable<>();
+ props.put("foo", "bar");
+ c.update(props);
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Provider.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Provider.java
new file mode 100644
index 0000000..75c2773
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/Provider.java
@@ -0,0 +1,26 @@
+/*
+ * 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.lambda.samples.compositefactory;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Provider {
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderComposite1.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderComposite1.java
new file mode 100644
index 0000000..bad0463
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderComposite1.java
@@ -0,0 +1,36 @@
+/*
+ * 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.lambda.samples.compositefactory;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProviderComposite1 {
+ private volatile LogService m_log;
+
+ public void bind(LogService log) {
+ m_log = log;
+ }
+
+ void start() {
+ m_log.log(LogService.LOG_INFO, "ProviderParticipant1.start()");
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderComposite2.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderComposite2.java
new file mode 100644
index 0000000..8386244
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderComposite2.java
@@ -0,0 +1,26 @@
+/*
+ * 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.lambda.samples.compositefactory;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProviderComposite2 {
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderFactory.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderFactory.java
new file mode 100644
index 0000000..3b35134
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderFactory.java
@@ -0,0 +1,62 @@
+/*
+ * 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.lambda.samples.compositefactory;
+
+import java.util.Dictionary;
+
+/**
+ * Pojo used to create all the objects composition used to implements the "Provider" Service.
+ * The manager is using a Configuration injected by Config Admin, in order to configure the
+ * various objects being part of the "Provider" service implementation.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProviderFactory {
+ private ProviderComposite1 m_composite1;
+ private ProviderComposite2 m_composite2;
+ private ProviderImpl m_providerImpl;
+ @SuppressWarnings("unused")
+ private Dictionary<String, Object> m_conf;
+
+ public void updated(Dictionary<String, Object> conf) {
+ // validate configuration and throw an exception if the properties are invalid
+ m_conf = conf;
+ }
+
+ /**
+ * Builds the composition of objects used to implement the "Provider" service.
+ * The Configuration injected by Config Admin will be used to configure the components
+ * @return The "main" object providing the "Provider" service.
+ */
+ ProviderImpl create() {
+ // Here, we can instantiate our object composition and configure them using the injected Configuration ...
+ m_composite1 = new ProviderComposite1(); // possibly configure this object using our configuration
+ m_composite2 = new ProviderComposite2(); // possibly configure this object using our configuration
+ m_providerImpl = new ProviderImpl(m_composite1, m_composite2);
+ return m_providerImpl; // Main object implementing the Provider service
+ }
+
+ /**
+ * Returns the
+ * @return
+ */
+ Object[] getComposition() {
+ return new Object[] { m_providerImpl, m_composite1, m_composite2 };
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderImpl.java
new file mode 100644
index 0000000..c874d71
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/ProviderImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.lambda.samples.compositefactory;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * This is the main implementation for our "Provider" service.
+ * This service is using a composition of two participants, which are used to provide the service
+ * (ProviderParticipant1, and ProviderParticipant2).
+ *
+ * This class is instantiated by the CompositionManager class.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProviderImpl implements Provider {
+ private final ProviderComposite1 m_participant1;
+ private final ProviderComposite2 m_participant2;
+ private volatile LogService m_log;
+
+ public void bind(LogService log) {
+ m_log = log;
+ }
+
+ ProviderImpl(ProviderComposite1 participant1, ProviderComposite2 participant2) {
+ m_participant1 = participant1;
+ m_participant2 = participant2;
+ }
+
+ void start() {
+ m_log.log(LogService.LOG_INFO, "ProviderImpl.start(): participants=" + m_participant1 + "," + m_participant2);
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/README b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/README
new file mode 100644
index 0000000..b9ab260
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/compositefactory/README
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+This Activator is an example usage of DM composite components. A composite component is implemented
+using a composition of multiple object instances, which are used to implement a given service.
+
+The sample also uses a Factory approach in order to instantiate the composition of objects: A
+"CompositionManager" is first injected with a Configuration that can possibly be used to create
+and configure all the composites.
+
+Dependencies are injected is some of the component implementation instances, using java8 method references. For instance,
+the LogService is only injected in the ProviderImpl and the ProviderComposite1 class and not in the ProviderComposite2 class.
+
+To see logs, type this command under the gogo shell:
+
+g! log info|grep compositefactory
+
+
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/Activator.java
new file mode 100644
index 0000000..978367c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/Activator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.lambda.samples.device;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.lambda.DependencyManagerActivator;
+import org.osgi.service.log.LogService;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyManagerActivator {
+ @Override
+ public void activate() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // Create a pair of Device/DeviceParameter service with id=1
+ createDeviceAndParameter(1);
+
+ // Create a pair of Device/DeviceParameter service with id=2
+ createDeviceAndParameter(2);
+
+ // Create a DeviceParameter adapter: for each pair of Device/DeviceParameter services having the same id,
+ // a DeviceParameter adapter service will be created.
+ adapter(Device.class, adpt -> adpt.provides(DeviceAccess.class).impl(DeviceAccessImpl.class));
+
+ // Creates a component that simply displays all available DeviceParameter adapter services.
+ component(comp -> comp
+ .impl(DeviceAccessConsumer.class)
+ .withSrv(LogService.class)
+ .withSrv(DeviceAccess.class, device -> device.cb(DeviceAccessConsumer::add)));
+ }
+
+ private void createDeviceAndParameter(int id) {
+ // Creates a Device service with the provided id.
+ component(comp -> comp.factory(() -> new DeviceImpl(id)).provides(Device.class, "device.id", id));
+
+ // Creates a DeivceParameter with the provided id.
+ component(comp -> comp.factory(() -> new DeviceParameterImpl(id)).provides(DeviceParameter.class, "device.id", id));
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/Device.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/Device.java
new file mode 100644
index 0000000..0e4cf10
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/Device.java
@@ -0,0 +1,26 @@
+/*
+ * 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.lambda.samples.device;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Device {
+ int getDeviceId();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccess.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccess.java
new file mode 100644
index 0000000..f9f0ec4
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccess.java
@@ -0,0 +1,30 @@
+/*
+ * 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.lambda.samples.device;
+
+/**
+ * Provides unified access to a pair of Device/DeviceParameter services having the same device ID.
+
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface DeviceAccess {
+ Device getDevice();
+
+ DeviceParameter getDeviceParameter();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccessConsumer.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccessConsumer.java
new file mode 100644
index 0000000..1d46839
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccessConsumer.java
@@ -0,0 +1,37 @@
+/*
+ * 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.lambda.samples.device;
+
+import java.util.Map;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DeviceAccessConsumer {
+ volatile LogService log;
+
+ void add(DeviceAccess deviceAccess, Map<String, Object> props) {
+ log.log(LogService.LOG_INFO, "DeviceAccessConsumer: Handling device access: id=" + props.get("device.access.id")
+ + "\n\t device=" + deviceAccess.getDevice()
+ + "\n\t device parameter=" + deviceAccess.getDeviceParameter()
+ + "\n\t device access properties=" + props);
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccessImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccessImpl.java
new file mode 100644
index 0000000..9a8e321
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceAccessImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.lambda.samples.device;
+
+import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;
+
+import org.apache.felix.dm.Component;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DeviceAccessImpl implements DeviceAccess {
+ volatile Device device;
+ volatile DeviceParameter deviceParameter;
+
+ void init(Component c) {
+ // Dynamically add an extra dependency on a DeviceParameter.
+ // Notice that we also add a "device.access.id" service property dynamically.
+
+ component(c, builder -> builder
+ .properties("device.access.id", device.getDeviceId())
+ .withSrv(DeviceParameter.class, srv -> srv.filter("(device.id=" + device.getDeviceId() + ")")));
+ }
+
+ @Override
+ public Device getDevice() {
+ return device;
+ }
+
+ @Override
+ public DeviceParameter getDeviceParameter() {
+ return deviceParameter;
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceImpl.java
new file mode 100644
index 0000000..6caacbe
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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.lambda.samples.device;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DeviceImpl implements Device {
+ final int id;
+
+ public DeviceImpl(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public int getDeviceId() {
+ return id;
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceParameter.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceParameter.java
new file mode 100644
index 0000000..f6efdab
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceParameter.java
@@ -0,0 +1,26 @@
+/*
+ * 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.lambda.samples.device;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface DeviceParameter {
+ int getDeviceId();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceParameterImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceParameterImpl.java
new file mode 100644
index 0000000..f7b9779
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/DeviceParameterImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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.lambda.samples.device;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DeviceParameterImpl implements DeviceParameter {
+ final int id;
+
+ public DeviceParameterImpl(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public int getDeviceId() {
+ return id;
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/README b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/README
new file mode 100644
index 0000000..d013c28
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/device/README
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+This is an example showing a Dependency Manager "Adapter" in action. Two kinds of services are
+registered in the registry: some Device, and some DeviceParameter services. For each Device (having
+a given id), there is also a corresponding "DeviceParameter" service, having the same id.
+
+Then a "DeviceAccessImpl" adapter service is defined: it is used to "adapt" the "Device" service to
+a "DeviceAccess" service, which provides the union of each pair of Device/DeviceParameter having the
+same device.id . The adapter also dynamically propagate the service properties of the adapted Device
+service.
+
+So see logs, just type this command under gogo shell:
+
+g! log info|grep device.api
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/Activator.java
new file mode 100644
index 0000000..a60db9c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/Activator.java
@@ -0,0 +1,62 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.lambda.DependencyManagerActivator;
+import org.osgi.service.log.LogService;
+import static org.apache.felix.service.command.CommandProcessor.COMMAND_FUNCTION;
+import static org.apache.felix.service.command.CommandProcessor.COMMAND_SCOPE;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyManagerActivator {
+ @Override
+ public void activate() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // Create the factory configuration for our DictionaryImpl service. An instance of the DictionaryImpl is created for each
+ // factory configuration that you add from webconsole (using the DictionaryConfiguration factory pid).
+ factoryPidAdapter(adapter -> adapter
+ .impl(DictionaryImpl.class)
+ .provides(DictionaryService.class)
+ .factoryPid(DictionaryConfiguration.class)
+ .propagate()
+ .cb(DictionaryImpl::updated)
+ .withSrv(LogService.class));
+
+ // Create the Dictionary Aspect that decorates any registered Dictionary service. For each Dictionary, an instance of the
+ // DictionaryAspect service is created).
+ aspect(DictionaryService.class, aspect -> aspect
+ .impl(DictionaryAspect.class)
+ .filter("(lang=en)").rank(10)
+ .withCnf(conf -> conf.pid(DictionaryAspectConfiguration.class).cb(DictionaryAspect::addWords))
+ .withSrv(LogService.class));
+
+ // Create the SpellChecker component. It depends on all available DictionaryService instances, possibly
+ // decorated by some DictionaryAspects.
+ component(comp -> comp
+ .impl(SpellChecker.class)
+ .provides(SpellChecker.class, COMMAND_SCOPE, "dictionary", COMMAND_FUNCTION, new String[] {"spellcheck"})
+ .withSrv(DictionaryService.class)
+ .withSrv(LogService.class));
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryAspect.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryAspect.java
new file mode 100644
index 0000000..1982db5
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryAspect.java
@@ -0,0 +1,84 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+import java.util.Dictionary;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.service.log.LogService;
+
+import aQute.bnd.annotation.metatype.Configurable;
+
+/**
+ * This aspect applies to the English DictionaryService, and allows to decorate it with some
+ * custom English words, which are configurable from WebConsole.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DictionaryAspect implements DictionaryService {
+ /**
+ * This is the service this aspect is applying to.
+ */
+ private volatile DictionaryService m_originalDictionary;
+
+ /**
+ * We store all configured words in a thread-safe data structure, because ConfigAdmin may
+ * invoke our updated method at any time.
+ */
+ private CopyOnWriteArrayList<String> m_words = new CopyOnWriteArrayList<String>();
+
+ /**
+ * We'll use the OSGi log service for logging. If no log service is available, then we'll
+ * use a NullObject.
+ */
+ private LogService m_log;
+
+ /**
+ * Defines a configuration dependency for retrieving our english custom words (by default,
+ * our PID is our full class name).
+ */
+ protected void addWords(Dictionary<String, ?> config) {
+ if (config != null) {
+ // We use the bnd "Configurable" helper in order to get an implementation for our DictionaryConfiguration interface.
+ DictionaryConfiguration cnf = Configurable.createConfigurable(DictionaryConfiguration.class, config);
+ m_words.clear();
+ for (String word : cnf.words()) {
+ m_words.add(word);
+ }
+ }
+ }
+
+ /**
+ * Our Aspect Service is starting and is about to be registered in the OSGi regsitry.
+ */
+ protected void start() {
+ m_log.log(LogService.LOG_INFO, "Starting aspect Dictionary with words: " + m_words
+ + "; original dictionary service=" + m_originalDictionary);
+ }
+
+ /**
+ * Checks if a word is found from our custom word list. if not, delegate to the decorated
+ * dictionary.
+ */
+ public boolean checkWord(String word) {
+ m_log.log(LogService.LOG_INFO, "DictionaryAspect: checking word " + word + " (original dictionary="
+ + m_originalDictionary + ")");
+ if (m_words.contains(word)) {
+ return true;
+ }
+ return m_originalDictionary.checkWord(word);
+ }
+
+ public String toString() {
+ return "DictionaryAspect: words=" + m_words + "; original dictionary=" + m_originalDictionary;
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryAspectConfiguration.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryAspectConfiguration.java
new file mode 100644
index 0000000..7b9d10a
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryAspectConfiguration.java
@@ -0,0 +1,37 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+import java.util.List;
+
+import aQute.bnd.annotation.metatype.Meta.AD;
+import aQute.bnd.annotation.metatype.Meta.OCD;
+
+/**
+ * This interface describes the configuration for our DictionaryAspect component. We are using the bnd metatype
+ * annotations, allowing to configure our Dictionary Services from web console.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@OCD(name="Spell Checker Dictionary Aspect",
+ description = "Declare here the list of english words to be added into the default english dictionary")
+public interface DictionaryAspectConfiguration {
+ @AD(description = "Dictionary aspect words")
+ List<String> words();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryConfiguration.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryConfiguration.java
new file mode 100644
index 0000000..12a4cd7
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+import java.util.List;
+
+import aQute.bnd.annotation.metatype.Meta.AD;
+import aQute.bnd.annotation.metatype.Meta.OCD;
+
+/**
+ * This interface describes the configuration for our DictionaryImpl component. We are using the bnd metatype
+ * annotations, allowing to configure our Dictionary Services from web console.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@OCD(name="Spell Checker Dictionary",
+ factory = true,
+ description = "Declare here some Dictionary instances, allowing to instantiates some DictionaryService services for a given dictionary language")
+public interface DictionaryConfiguration {
+ @AD(description = "Describes the dictionary language", deflt = "en")
+ String lang();
+
+ @AD(description = "Declare here the list of words supported by this dictionary.")
+ List<String> words();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryImpl.java
new file mode 100644
index 0000000..4167e77
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryImpl.java
@@ -0,0 +1,96 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+import java.util.Dictionary;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.service.log.LogService;
+
+import aQute.bnd.annotation.metatype.Configurable;
+
+/**
+ * A Dictionary Service, instantiated from webconsole, when you add some configurations instances to the
+ * DictionaryConfiguration factory pid. The Configuration metatype informations is described using the
+ * bnd metatype information (see the DictionaryConfiguration interface).
+ *
+ * You must configure at least one Dictionary from web console, since the SpellCheck won't start if no Dictionary
+ * Service is available.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DictionaryImpl implements DictionaryService {
+ /**
+ * The key of our config admin dictionary values.
+ */
+ final static String WORDS = "words";
+
+ /**
+ * We store all configured words in a thread-safe data structure, because ConfigAdmin
+ * may invoke our updated method at any time.
+ */
+ private CopyOnWriteArrayList<String> m_words = new CopyOnWriteArrayList<String>();
+
+ /**
+ * We'll use the OSGi log service for logging. If no log service is available, then we'll use a NullObject.
+ */
+ private LogService m_log;
+
+ /**
+ * Our Dictionary language.
+ */
+ private String m_lang;
+
+ /**
+ * Our service will be initialized from ConfigAdmin.
+ * @param config The configuration where we'll lookup our words list (key=".words").
+ */
+ protected void updated(Dictionary<String, ?> config) {
+ if (config != null) {
+ // We use the bnd "Configurable" helper in order to get an implementation for our DictionaryConfiguration interface.
+ DictionaryConfiguration cnf = Configurable.createConfigurable(DictionaryConfiguration.class, config);
+
+ m_lang = cnf.lang();
+ m_words.clear();
+ for (String word : cnf.words()) {
+ m_words.add(word);
+ }
+ }
+ }
+
+ /**
+ * A new Dictionary Service is starting (because a new factory configuration has been created
+ * from webconsole).
+ */
+ protected void start() {
+ m_log.log(LogService.LOG_INFO, "Starting Dictionary Service with language: " + m_lang);
+ }
+
+ /**
+ * Check if a word exists if the list of words we have been configured from ConfigAdmin/WebConsole.
+ */
+ public boolean checkWord(String word) {
+ return m_words.contains(word);
+ }
+
+ @Override
+ public String toString() {
+ return "Dictionary: language=" + m_lang + ", words=" + m_words;
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryService.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryService.java
new file mode 100644
index 0000000..535210a
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/DictionaryService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+/**
+ * A simple service interface that defines a dictionary service. A dictionary
+ * service simply verifies the existence of a word.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface DictionaryService {
+ /**
+ * Check for the existence of a word.
+ *
+ * @param word the word to be checked.
+ * @return true if the word is in the dictionary, false otherwise.
+ */
+ public boolean checkWord(String word);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/README b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/README
new file mode 100644
index 0000000..2dda5b8
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/README
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+This sample shows a "SpellChecker" application (using DM API) which provides a
+"dictionary:spellcheck" GOGO shell command. The GOGO "dictionary:spellcheck" command accepts a
+string as parameter, which is checked for proper existence. The SpellChecker class has a
+required/multiple (1..N) dependency over every available "DictionaryService" services, which are
+internally used by the SpellChecker command, when checking word existence.
+
+A DictionaryService is defined using a FactoryConfigurationAdapterService , allowing to instantiate
+many "DictionaryService" instances for each configuration that are added to the
+factory pid "Spell Checker Configuration (api)" from web console.
+The factory pid configuration metatypes are defined using the bnd "metatype" annotations
+(see DictionaryConfiguration.java).
+
+The DictionaryService is decorated with a DictionaryAspect, which you can instantiate by adding a
+configuration to the "Spell Checker Aspect Dictionary (api)" pid from web console. The
+aspect configuration metatype is also declared using the bnd metatype annotations (see
+DictionaryAspectConfiguration.java).
+
+Before running this sample, go to webconsole, and add some words in the Spell Checker Configuration (api) factory PID, and
+in the Spell Checker Aspect Dictionary (api) PID.
+
+Then go to gogo shell, and type dm help. You will normally see the dictionary:spellcheck command.
+Type dictionary:spellcheck <some words configured either in the spell checker configuration, or in the spell checker aspect configuration,
+and the dictionary will check for proper word existance in the configuration.
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/SpellChecker.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/SpellChecker.java
new file mode 100644
index 0000000..6429643
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/dictionary/SpellChecker.java
@@ -0,0 +1,76 @@
+/*
+ * 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.lambda.samples.dictionary;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.felix.service.command.Descriptor;
+import org.osgi.service.log.LogService;
+
+/**
+ * Felix "spellcheck" Gogo Shell Command. This command allows to check if some given words are valid or not.
+ * This command will be activated only if (at least) one DictionaryService has been injected.
+ * To create a Dictionary Service, you have to go the the web console and add a configuration in the
+ * "Dictionary Configuration" factory pid.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SpellChecker {
+ /**
+ * We'll use the OSGi log service for logging. If no log service is available, then we'll use a NullObject.
+ */
+ private volatile LogService m_log;
+
+ /**
+ * We'll store all Dictionaries in a concurrent list, in order to avoid method synchronization.
+ * (Auto-Injected from Activator, at any time). DependencyManager detects that the field is an
+ * Iterable of a DictionaryService and automatically adds any available DictionaryService, at any time.
+ */
+ private final Iterable<DictionaryService> m_dictionaries = new ConcurrentLinkedQueue<>();
+
+ /**
+ * Lifecycle method callback, used to check if our service has been activated.
+ */
+ protected void start() {
+ m_log.log(LogService.LOG_WARNING, "Spell Checker started");
+ }
+
+ /**
+ * Lifecycle method callback, used to check if our service has been activated.
+ */
+ protected void stop() {
+ m_log.log(LogService.LOG_WARNING, "Spell Checker stopped");
+ }
+
+ // --- Gogo Shell command
+
+ @Descriptor("checks if word is found from an available dictionary")
+ public void spellcheck(@Descriptor("the word to check") String word) {
+ m_log.log(LogService.LOG_INFO, "Checking spelling of word \"" + word + "\" using the following dictionaries: "
+ + m_dictionaries);
+
+ for (DictionaryService dictionary : m_dictionaries) {
+ if (dictionary.checkWord(word)) {
+ System.out.println("word " + word + " is correct");
+ return;
+ }
+ }
+ System.err.println("word " + word + " is incorrect");
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/Activator.java
new file mode 100644
index 0000000..3f4080b
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/Activator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.lambda.samples.factory;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.lambda.DependencyManagerActivator;
+import org.osgi.service.log.LogService;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyManagerActivator {
+ @Override
+ public void activate() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ component(comp -> comp
+ .factory(ProviderFactory::new, ProviderFactory::create)
+ .provides(Provider.class)
+ .start(ProviderImpl::start)
+ .withSrv(LogService.class, log -> log.required().cb(ProviderImpl::set)));
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/Provider.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/Provider.java
new file mode 100644
index 0000000..7b06e63
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/Provider.java
@@ -0,0 +1,25 @@
+/*
+ * 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.lambda.samples.factory;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Provider {
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/ProviderFactory.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/ProviderFactory.java
new file mode 100644
index 0000000..c90770e
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/ProviderFactory.java
@@ -0,0 +1,7 @@
+package org.apache.felix.dm.lambda.samples.factory;
+
+public class ProviderFactory {
+ public ProviderImpl create() {
+ return new ProviderImpl();
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/ProviderImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/ProviderImpl.java
new file mode 100644
index 0000000..220958e
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/ProviderImpl.java
@@ -0,0 +1,38 @@
+/*
+ * 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.lambda.samples.factory;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * This is the main implementation for our "Provider" service.
+ * This service is using a composition of two participants, which are used to provide the service
+ * (ProviderParticipant1, and ProviderParticipant2).
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProviderImpl implements Provider {
+ private volatile LogService m_log;
+
+ void set(LogService log) { m_log = log; }
+
+ void start() {
+ m_log.log(LogService.LOG_INFO, "ProviderImpl.start()");
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/README b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/README
new file mode 100644
index 0000000..3093738
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/factory/README
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+This sample is an example usage of DM components that are created using a Factory object.
+The Factory is defined using java8 method references.
+
+To see logs, type this command under the gogo shell:
+
+g! log info|grep compositefactory
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/Activator.java
new file mode 100644
index 0000000..117af23
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/Activator.java
@@ -0,0 +1,64 @@
+/*
+ * 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.lambda.samples.future;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.lambda.DependencyManagerActivator;
+import org.osgi.service.log.LogService;
+
+/**
+ * This examples show how to use the new "Future" dependency available from the dependencymanager-lambda library.
+ * The PageLink component provides the list of available hrefs found from the Felix web site.
+ * The page is downloaded asynchronously using a CompletableFuture, and the component of the PageLinkImpl class
+ * will wait for the completion of the future before start.
+ *
+ * The interesting thing to look at is located in the PageLinkImpl.init() method.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyManagerActivator {
+ /**
+ * Initialize our components using new DM-lambda activator base.
+ */
+ @Override
+ public void activate() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // System.setProperty("http.proxyHost","your.http.proxy.host");
+ // System.setProperty("http.proxyPort", "your.http.proxy.port");
+
+ // Create the PageLinks service, which asynchronously download the content of the Felix web page.
+ // The PageLink service will be started once the page has been downloaded (using a CompletableFuture).
+ component(comp -> comp
+ .factory(() -> new PageLinksImpl("http://felix.apache.org/"))
+ .provides(PageLinks.class)
+ .withSrv(LogService.class, log -> log.cb(PageLinksImpl::bind)));
+
+ // Just wait for the PageLinks service and display all links found from the Felix web site.
+ component(comp -> comp.impl(this).withSrv(PageLinks.class, page -> page.cbi(this::setPageLinks)));
+ }
+
+ /**
+ * display all the hrefs (links) found from the Felix web site.
+ */
+ void setPageLinks(PageLinks page) {
+ out.println("Felix site links: " + page.getLinks());
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/PageLinks.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/PageLinks.java
new file mode 100644
index 0000000..37eda50
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/PageLinks.java
@@ -0,0 +1,10 @@
+package org.apache.felix.dm.lambda.samples.future;
+
+import java.util.List;
+
+/**
+ * Service that displays all links found from a given web page.
+ */
+public interface PageLinks {
+ List<String> getLinks();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/PageLinksImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/PageLinksImpl.java
new file mode 100644
index 0000000..c6e0895
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/PageLinksImpl.java
@@ -0,0 +1,81 @@
+package org.apache.felix.dm.lambda.samples.future;
+
+import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import java.util.concurrent.CompletableFuture;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.dm.Component;
+import org.osgi.service.log.LogService;
+
+/**
+ * Provides all hrefs found from a given web page.
+ */
+public class PageLinksImpl implements PageLinks {
+ private LogService m_log;
+ private final static String HREF_PATTERN = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
+ private List<String> m_links; // web page hrefs (links).
+ private String m_url;
+
+ PageLinksImpl(String url) {
+ m_url = url;
+ }
+
+ void bind(LogService log) {
+ m_log = log;
+ }
+
+ void init(Component c) {
+ // asynchronously download the content of the URL specified in the constructor.
+ CompletableFuture<List<String>> futureLinks = CompletableFuture.supplyAsync(() -> download(m_url))
+ .thenApply(this::parseLinks);
+
+ // Add the future dependency so we'll be started once the CompletableFuture "futureLinks" has completed.
+ component(c, comp -> comp.withFuture(futureLinks, links -> links.cbi(this::setLinks)));
+ }
+
+ // Called when our future has completed.
+ void setLinks(List<String> links) {
+ m_links = links;
+ }
+
+ // once our future has completed, our component is started.
+ void start() {
+ m_log.log(LogService.LOG_INFO, "Service starting: number of links found from Felix web site: " + m_links.size());
+ }
+
+ @Override
+ public List<String> getLinks() {
+ return m_links;
+ }
+
+ private String download(String url) {
+ try (Scanner in = new Scanner(new URL(url).openStream())) {
+ StringBuilder builder = new StringBuilder();
+ while (in.hasNextLine()) {
+ builder.append(in.nextLine());
+ builder.append("\n");
+ }
+ return builder.toString();
+ } catch (IOException ex) {
+ RuntimeException rex = new RuntimeException();
+ rex.initCause(ex);
+ throw rex;
+ }
+ }
+
+ private List<String> parseLinks(String content) {
+ Pattern pattern = Pattern.compile(HREF_PATTERN, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = pattern.matcher(content);
+ List<String> result = new ArrayList<>();
+ while (matcher.find())
+ result.add(matcher.group(1));
+ return result;
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/README b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/README
new file mode 100644
index 0000000..a72c0f1
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/future/README
@@ -0,0 +1,16 @@
+The purpose of this sample is to show an example usage of the new "CompletableFuture" dependency that has been
+added in the dm-lambda library. CompletableFuture java8 class provides functional operations and promotes an asynchronous event-driven model.
+
+In such model, you can use the new dm-lambda library to add dependencies on asynchronous events using the standard JDK CompletableFuture class.
+
+In this example, the Activator first defines a PageLink component that is used to download a given page from the web. The service then parses
+the content of the page and returns all available hrefs (links) found from the web page.
+
+The PageLink is initialized with the Felix web site URL, which is asynchronously downloaded from the PageLink::init method, using a CompletableFuture.
+The CF is then added as a "FutureDependency" in the PageLinkImpl.init() method, and when the CF completes, the PageLinkImpl.start() callback is invoked
+and the service is registered.
+
+The Activator is then getting injected with the PageLink service, and displays the links (hrefs) found from the Felix web site.
+
+Caution: if you are using a corporate http proxy, you have to fix the Activator in order to configure the ip addr and port number of your
+http proxy.
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/Activator.java
new file mode 100644
index 0000000..e36a7f2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/Activator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.lambda.samples.hello;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.lambda.DependencyManagerActivator;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.log.LogService;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyManagerActivator {
+ @Override
+ public void activate() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // Creates a Service Provider
+ component(comp -> comp
+ .impl(ServiceProviderImpl.class)
+ .provides(ServiceProvider.class, property1 -> "value1", property2 -> 123) // property names are deduced from lambda parameter names
+ .start(ServiceProviderImpl::activate)
+ .withSrv(LogService.class, log -> log.cb(ServiceProviderImpl::bind)));
+
+ // Creates a Service Consumer. Notice that if your configuration callback is "updated", you can
+ // simply use "withCnf(pid)" instead of explicitely providing the method reference.
+
+ component(comp -> comp
+ .impl(ServiceConsumer.class)
+ .withSrv(LogService.class)
+ .withSrv(ServiceProvider.class, srv -> srv.filter("(property1=value1)"))
+ .withCnf(conf -> conf.pid(ServiceConsumer.class).cb(ServiceConsumer::updated)));
+
+ // Same as above, but using a shorter form of "withCnf" declaration
+// component(comp -> comp
+// .impl(ServiceConsumer.class)
+// .withSrv(LogService.class)
+// .withSrv(ServiceProvider.class, srv -> srv.filter("(property1=value1)"))
+// .withCnf(ServiceConsumer.class));
+
+ // Creates a component that populates some properties in the Configuration Admin.
+ component(comp -> comp.impl(Configurator.class).withSrv(ConfigurationAdmin.class));
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/Configurator.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/Configurator.java
new file mode 100644
index 0000000..544c7cb
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/Configurator.java
@@ -0,0 +1,20 @@
+package org.apache.felix.dm.lambda.samples.hello;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class Configurator {
+ volatile ConfigurationAdmin m_cm; // injected by reflection.
+
+ void start() throws IOException {
+ // Configure the ServiceConsumer component
+ Configuration c = m_cm.getConfiguration(ServiceConsumer.class.getName(), null);
+ Dictionary<String, Object> props = new Hashtable<>();
+ props.put("foo", "bar");
+ c.update(props);
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/README b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/README
new file mode 100644
index 0000000..d762a3c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/README
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+This sample provides a DM Activator declaring one service consumer and a service provider. The
+ServiceConsumer is also depending on a configuration pid (see org.apache.felix.dependencymanager.samples.hello.Configurator).
+To see logs, just type this under gogo shell:
+
+g! log info|grep hello.annot
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceConsumer.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceConsumer.java
new file mode 100644
index 0000000..3762789
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceConsumer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.lambda.samples.hello;
+
+import java.util.Dictionary;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * Our service consumer. We depend on a ServiceProvider, and on a configuration.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceConsumer {
+ volatile ServiceProvider service;
+ volatile LogService log;
+ Dictionary<?, ?> conf;
+
+ public void updated(Dictionary<String, Object> conf) {
+ this.conf = conf;
+ }
+
+ public void start() {
+ log.log(LogService.LOG_INFO, "ServiceConsumer.start: calling service.hello()");
+ this.service.hello();
+ }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceProvider.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceProvider.java
new file mode 100644
index 0000000..2c34285
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceProvider.java
@@ -0,0 +1,28 @@
+/*
+ * 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.lambda.samples.hello;
+
+/**
+ * The interface for our service provider.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ServiceProvider {
+ public void hello();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceProviderImpl.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceProviderImpl.java
new file mode 100644
index 0000000..221b75c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dm/lambda/samples/hello/ServiceProviderImpl.java
@@ -0,0 +1,41 @@
+/*
+ * 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.lambda.samples.hello;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * The implementation for our service provider.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceProviderImpl implements ServiceProvider {
+ volatile LogService log;
+
+ void bind(LogService log) { this.log = log; }
+
+ void activate() {
+ log.log(LogService.LOG_INFO, "ServiceProviderImpl.start");
+ }
+
+ @Override
+ public void hello() {
+ log.log(LogService.LOG_INFO, "ServiceProviderImpl.hello");
+ }
+}