You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2015/12/13 23:24:02 UTC
svn commit: r1719841 [4/7] - in /felix/sandbox/pderop:
dependencymanager-lambda/ dependencymanager-lambda/RemoteSystemsTempFiles/
dependencymanager-lambda/cnf/ dependencymanager-lambda/cnf/bin/
dependencymanager-lambda/cnf/buildrepo/ dependencymanager-...
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryAspect.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/DictionaryAspect.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryAspect.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryAspect.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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;
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryAspectConfiguration.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/DictionaryAspectConfiguration.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryAspectConfiguration.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryAspectConfiguration.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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 Aspect Dictionary (api)",
+ 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();
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryConfiguration.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/DictionaryConfiguration.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryConfiguration.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryConfiguration.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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 (api)",
+ 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();
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryImpl.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/DictionaryImpl.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryImpl.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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;
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryService.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/DictionaryService.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryService.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/DictionaryService.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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);
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/README
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/README?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/README (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/README Sun Dec 13 22:23:57 2015
@@ -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 when some configurations are added to the
+"Spell Checker Configuration (api)" factory pid 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.
+
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/SpellChecker.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/SpellChecker.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/SpellChecker.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/dictionary/SpellChecker.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,75 @@
+/*
+ * 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.dependencymanager.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).
+ */
+ 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");
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/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/factory/Activator.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Activator.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Activator.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.lambda.samples.factory;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.builder.lambda.DependencyActivatorBase;
+import org.osgi.service.log.LogService;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyActivatorBase {
+ @Override
+ public void init() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ component(comp -> comp
+ .provides(Provider.class)
+ .factory(ProviderFactory::new, ProviderFactory::create)
+ .withService(LogService.class, srv -> srv.required().onAdd(ProviderImpl::set))
+ .onStart(ProviderImpl::start));
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Provider.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/factory/Provider.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Provider.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/Provider.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.lambda.samples.factory;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Provider {
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.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/factory/ProviderFactory.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderFactory.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,7 @@
+package org.apache.felix.dependencymanager.lambda.samples.factory;
+
+public class ProviderFactory {
+ public Object create() {
+ return new ProviderImpl();
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderImpl.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/factory/ProviderImpl.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/ProviderImpl.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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()");
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/README
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/README?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/README (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/factory/README Sun Dec 13 22:23:57 2015
@@ -0,0 +1,27 @@
+/*
+ * 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 composite components. A composite component is implemented
+using a composition of multiple object instances, which are used to implement a given complex
+service. Here, we define a "Provider" service, which is implemented by three object instances:
+ProviderImpl, ProviderParticipant1, ProviderParticipant2.
+
+Dependencies are injected in all objects being part of the composition.
+
+To see logs, type this command under the gogo shell:
+
+g! log info|grep compositefactory
Added: 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=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,53 @@
+/*
+ * 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.dependencymanager.lambda.samples.future;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.builder.lambda.DependencyActivatorBase;
+import org.osgi.service.log.LogService;
+
+/**
+ * Defines two components: FelixSite which provides some informations about the Felix Web site,
+ * and Test, which depends in the FelixSite service.
+ *
+ * The FelixSite component will asynchronously download the Felix web page, and uses a "CompletableFuture"
+ * dependency, in order to block the activation of the FelixSite service, until the web page is downloaded and parsed.
+ *
+ * The download is done using some CompletableFuture asynchronous tasks.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyActivatorBase {
+ @Override
+ public void init() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // Define the FelixSiteInfo component that provides some informations about the Felix web site.
+ component(comp -> comp
+ .provides(SiteInfo.class)
+ .factory(() -> new SiteInfoImpl("http://felix.apache.org/"))
+ .withService(LogService.class, srv -> srv.onAdd(SiteInfoImpl::bind)));
+
+ // Define the FelixSite component that depends on the FelixSiteInfo service
+ component(comp -> comp
+ .impl(DisplaySite.class)
+ .withService(LogService.class).withService(SiteInfo.class));
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/DisplaySite.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/DisplaySite.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/DisplaySite.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/DisplaySite.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,13 @@
+package org.apache.felix.dependencymanager.lambda.samples.future;
+
+import org.osgi.service.log.LogService;
+
+public class DisplaySite {
+ volatile SiteInfo m_siteInfo;
+ volatile LogService m_log;
+
+ void start() {
+ m_log.log(LogService.LOG_INFO, "DisplaySite.start(): links available from the Felix web site: " + m_siteInfo.getLinks());
+ }
+
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README
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/README?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README Sun Dec 13 22:23:57 2015
@@ -0,0 +1,54 @@
+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.
+
+But when you go for asynchronous model, then in some situation you have to take care. For instance assuming you want to
+initialize a component from the init method using some asynchronous stuff, then the init method may return before the async operations
+have completed; and the component.start() callback may then be called too early. And what about if you want to add dependencies from the init() method
+and you want to wait for the async operations before adding the dependency ? In this case you would have to block on the CompletableFuture
+but this is something you don't want to do.
+
+So, to avoid blocking or some boilerplate code, a new (required) CompletableFuture dependency has been added (in the dm-lambda library),
+and you can use it to block the component in the init state, until a given "CompletableFuture" completes.
+The new dependency is implemented as all other dependencies, and it extends the org.apache.felix.dm.context.AbstractDependency class.
+
+Now, let's describe the sample: we have a "SiteInfoImpl" component that is using a CompletableFuture from its init method
+in order to asynchronously download and parse an URL from the web. When the page content is downloaded, then the hrefs
+(links) contained in the URL page are parsed. The component state remains in the init state until the page is downloaded.
+
+Here is the activator:
+
+public class Activator extends DependencyActivatorBase {
+ @Override
+ public void init() throws Exception {
+ // Define the SiteInfo component that provides some informations about the Felix web site.
+ component(comp -> comp
+ .provides(SiteInfo.class)
+ .factory(() -> new SiteInfoImpl("http://felix.apache.org/"))
+ .withService(LogService.class, srv -> srv.onAdd(SiteInfoImpl::bind)));
+
+ // Define a component that depends on the SiteInfo service
+ component(comp -> comp
+ .impl(DisplaySite.class)
+ .withService(LogService.class).withService(SiteInfo.class));
+ }
+}
+
+Nothing special so far.
+
+Now let's take a look at the SiteInfoImpl.init() method:
+
+ void init(Component c) {
+ // Asynchronously download and parse the links from the web page.
+ // We use a completable future that is then added as a dependency to our component, which
+ // will be started once the future has completed.
+
+ CompletableFuture<List<String>> links =
+ CompletableFuture.supplyAsync(() -> downloadSite(m_url))
+ .thenApply(this::getSiteLinks);
+
+ component(c, builder -> builder.withFuture(", b -> b.thenAccept(this::setLinks)));
+ }
+
+So, the "builder.withFuture(links, b -> b.thenAccept(this::setLinks))" code simply defines a "completable future" dependency that will be available once the
+"links" future has completed, and the method reference passed to the b.thenAccept method will be invoked exactly if you would have invoked
+the same method on the CompletableFuture "links" object.
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfo.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/SiteInfo.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfo.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfo.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,16 @@
+package org.apache.felix.dependencymanager.lambda.samples.future;
+
+import java.util.List;
+
+/**
+ * A Service which provides informations about the Felix web site.
+ */
+public interface SiteInfo {
+
+ /**
+ * Returns the links (href) available from the Felix web site.
+ * @return the links available from the Felix web site
+ */
+ List<String> getLinks();
+
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.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/SiteInfoImpl.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,88 @@
+package org.apache.felix.dependencymanager.lambda.samples.future;
+
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.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;
+
+/**
+ * A Component which provides general informations about a given web site
+ * (this simple example just displays the number of links it finds from a given URL.
+ * The url is retrieved asynchronously using a CompletableFuture class.
+ * The Component is also using a "withFuture" dependency that allows to wait for the
+ * completion of the CompletableFuture, before registering the SiteInfo OSGi service.
+ */
+public class SiteInfoImpl implements SiteInfo {
+ private LogService m_log;
+ final static String HREF_PATTERN = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
+ List<String> m_links; // web page hrefs (links).
+ final String m_url;
+
+ public SiteInfoImpl(String url) {
+ m_url = url;
+ }
+
+ void bind(LogService log) {
+ m_log = log;
+ }
+
+ void init(Component c) {
+ // Asynchronously calculate the number of links from the web site.
+ // We use a completable future that is then added as a dependency to our component, which
+ // will be started on the future has completed.
+
+ CompletableFuture<List<String>> links =
+ CompletableFuture.supplyAsync(() -> downloadSite(m_url))
+ .thenApply(this::getSiteLinks);
+
+ component(c, builder -> builder.withFuture(links, b -> b.thenAccept(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 " + m_url + ": " + m_links.size());
+ }
+
+ @Override
+ public List<String> getLinks() {
+ return m_links;
+ }
+
+ private String downloadSite(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;
+ }
+ }
+
+ List<String> getSiteLinks(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;
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/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/hello/Activator.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/Activator.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/Activator.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.lambda.samples.hello;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.builder.lambda.DependencyActivatorBase;
+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 DependencyActivatorBase {
+ @Override
+ public void init() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ component(comp -> comp
+ .provides(ServiceProvider.class)
+ .onStart(ServiceProviderImpl::activate)
+ .properties("foo", "bar", "gabu", "zo") // foo=bar, gabu=zo
+ .impl(ServiceProviderImpl.class)
+ .withService(LogService.class, srv -> srv.onAdd(ServiceProviderImpl::bind)));
+
+ component(comp -> comp
+ .impl(ServiceConsumer.class)
+ .withService(LogService.class)
+ .withService(ServiceProvider.class, srv -> srv.filter("(foo=bar)"))
+ .withConfiguration(conf -> conf.pid(ServiceConsumer.class).onUpdate(ServiceConsumer::updated)));
+
+ component(comp -> comp.impl(Configurator.class).withService(ConfigurationAdmin.class));
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/Configurator.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/hello/Configurator.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/Configurator.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/Configurator.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,20 @@
+package org.apache.felix.dependencymanager.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);
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/README
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/README?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/README (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/README Sun Dec 13 22:23:57 2015
@@ -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
+
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceConsumer.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/hello/ServiceConsumer.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceConsumer.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceConsumer.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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();
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceProvider.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/hello/ServiceProvider.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceProvider.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceProvider.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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();
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceProviderImpl.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/hello/ServiceProviderImpl.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceProviderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/hello/ServiceProviderImpl.java Sun Dec 13 22:23:57 2015
@@ -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.dependencymanager.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");
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/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/rx/completable/Activator.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/Activator.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/Activator.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,53 @@
+/*
+ * 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.dependencymanager.lambda.samples.rx.completable;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.builder.lambda.DependencyActivatorBase;
+import org.osgi.service.log.LogService;
+
+/**
+ * Defines two components: FelixSite which provides some informations about the Felix Web site,
+ * and Test, which depends in the FelixSite service.
+ *
+ * The FelixSite component will asynchronously download the Felix web page, and uses a "CompletableFuture"
+ * dependency, in order to block the activation of the FelixSite service, until the web page is downloaded and parsed.
+ *
+ * The download is done using some CompletableFuture asynchronous tasks.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator extends DependencyActivatorBase {
+ @Override
+ public void init() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+
+ // Define the FelixSiteInfo component that provides some informations about the Felix web site.
+ component(comp -> comp
+ .provides(SiteInfo.class)
+ .factory(() -> new SiteInfoImpl("http://felix.apache.org/"))
+ .withService(LogService.class, srv -> srv.onAdd(SiteInfoImpl::bind)));
+
+ // Define the FelixSite component that depends on the FelixSiteInfo service
+ component(comp -> comp
+ .impl(DisplaySite.class)
+ .withService(LogService.class).withService(SiteInfo.class));
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/DisplaySite.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/rx/completable/DisplaySite.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/DisplaySite.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/DisplaySite.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,13 @@
+package org.apache.felix.dependencymanager.lambda.samples.rx.completable;
+
+import org.osgi.service.log.LogService;
+
+public class DisplaySite {
+ volatile SiteInfo m_siteInfo;
+ volatile LogService m_log;
+
+ void start() {
+ m_log.log(LogService.LOG_INFO, "DisplaySite.start(): links available from the Felix web site: " + m_siteInfo.getLinks());
+ }
+
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/ObservableCompletableFuture.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/rx/completable/ObservableCompletableFuture.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/ObservableCompletableFuture.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/ObservableCompletableFuture.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,23 @@
+package org.apache.felix.dependencymanager.lambda.samples.rx.completable;
+
+import java.util.concurrent.CompletableFuture;
+
+import io.reactivex.Observable;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+
+class ObservableCompletableFuture<T> extends CompletableFuture<T> {
+ private final Disposable m_subscription;
+
+ public ObservableCompletableFuture(Observable<T> observable) {
+ m_subscription = observable
+ .subscribeOn(Schedulers.io())
+ .subscribe(this::complete, this::completeExceptionally);
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ m_subscription.dispose();
+ return super.cancel(mayInterruptIfRunning);
+ }
+}
\ No newline at end of file
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/README
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/README?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/README (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/README Sun Dec 13 22:23:57 2015
@@ -0,0 +1,106 @@
+The purpose of this sample is to experiment RxJava(2.0) and DependencyManager lambda; and to check if some hooks have
+to be added into DM-lambda in order to build some RxJava applications on top it.
+
+So, in this sample, we have a use case where RxJava is used to download and parse an URL from the web, in order to count the number of
+hrefs (links) contained in the URL page, and we do this from a component.init() method.
+Now, the problem is that the page is downloaded asynchronously using RxJava, and when the component init() method returns,
+any services implemented by the component are registered. Moreover, the component start() method is called while the download is still pending.
+
+So, ultimately, we would need some kind of required dependency on something in order to make sure that the component remains in the
+init state, until the page has been downloaded and parsed.
+
+Now, there is something new to DM-lambda: a new kind of dependency has been introduced: you can now
+define a dependency on a "CompletableFuture", using the "ComponentBuilder.withFuture" method.
+Such dependency allows to block the activation of a component (its a required dependency) until a given completableFuture completes.
+
+Here is an example: you have a Download component and from the Activator, you declare this:
+
+public class Activator extends DependencyActivatorBase {
+ public void init() throws Exception {
+ CompletableFuture<String> pageFuture =
+ CompletableFuture.supplyAsync(() -> downloadSite("http://felix.apache.org/"))
+
+ component(comp -> comp
+ .provides(DownloadService.class)
+ .impl(Download.class)
+ .withService(LogService.class, srv -> srv.onAdd(FelixSiteImpl::bind))
+ .withFuture(pageFuture, depbuilder -> depbuilder.thenAccept(content -> Download::setContent)));
+
+ }
+}
+
+Here, notice the new "withFuture" dependency: it's a required dependency that takes a CompletableFuture (pageFuture), and also the
+callback that will be invoked when the future will have completed (thenAccept).
+The "thenAccept" method has the same purpose as the one from the CompletableFuture.thenAccept method.
+
+So, now, the nice thing is that wrapping an RxObservable to CompletableFuture is simple and can be done using the following helper class:
+
+class ObservableCompletableFuture<T> extends CompletableFuture<T> {
+ private final Disposable m_subscription;
+
+ public ObservableCompletableFuture(Observable<T> observable) {
+ m_subscription = observable
+ .subscribeOn(Schedulers.io())
+ .subscribe(this::complete, this::completeExceptionally);
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ m_subscription.dispose();
+ return super.cancel(mayInterruptIfRunning);
+ }
+}
+
+This simple class takes in the constructor an Observable<T>, and subscribes to it.
+So, when the Observable completes, the "this::complete" calls the CompletableFuture.complete() method in order
+to propagate the completion of the Observable to the CompletableFuture.
+
+Now let's go with a concrete example: Using this class above allows to build nice DM components without boilerplate code, like this:
+
+1) from the Activator, you can for example define a service providing component like this:
+
+Activator.java:
+
+ // Define the FelixSiteInfo component that provides some informations about the Felix web site.
+ component(comp -> comp
+ .provides(SiteInfo.class)
+ .impl(SiteInfoImpl.class)
+ .withService(LogService.class, srv -> srv.onAdd(SiteInfoImpl::bind)));
+
+ 2) and from the SiteInfoImpl.init() method:
+
+ FelixSiteImpl.java:
+
+ void init(Component c) {
+ // Asynchronously calculate the number of links from the Felix web site.
+ // We use Rx to define an asynchrous Observable task, and we wrap it to a CompletableFuture
+ // that is used as a Dependency Manager "Future" dependency, in order to block the activation of
+ // our component until the felix site has been downloaded and parsed.
+
+ Observable<List<String>> links = downloadSite("http://felix.apache.org/")
+ .map(this::getSiteLinks);
+
+ component(c, comp -> comp
+ .withFuture(toFuture(links), futuredep -> futuredep.thenAccept(this::setLinks)));
+ }
+
+ // Called when our future has completed.
+ void setLinks(List<String> links) {
+ m_felixLinks = 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 Apache Felix site=" + m_felixLinks.size());
+ }
+
+The important part to understand is the following:
+
+
+ component(c, comp -> comp
+ .withFuture(toFuture(links), futuredep -> futuredep.thenAccept(this::setLinks)));
+
+here, we wrap the links (which is an Observable<List<String>> into the ObservableCompletableFuture helper that was
+presented previously. And when the CompletableFuture will complete , it will call the "thenAccept(this::setLinks)" method in order to inject
+the result into the component before the component.start() method, exactly in the same manner when a required dependency is injected before start().
\ No newline at end of file
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/SiteInfo.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/rx/completable/SiteInfo.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/SiteInfo.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/SiteInfo.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,16 @@
+package org.apache.felix.dependencymanager.lambda.samples.rx.completable;
+
+import java.util.List;
+
+/**
+ * A Service which provides informations about the Felix web site.
+ */
+public interface SiteInfo {
+
+ /**
+ * Returns the links (href) available from the Felix web site.
+ * @return the links available from the Felix web site
+ */
+ List<String> getLinks();
+
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/SiteInfoImpl.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/rx/completable/SiteInfoImpl.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/SiteInfoImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/completable/SiteInfoImpl.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,106 @@
+package org.apache.felix.dependencymanager.lambda.samples.rx.completable;
+
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.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;
+
+import io.reactivex.Observable;
+
+/**
+ * A Component which provides general informations about a given web site
+ * (this simple example just displays the number of links it finds from a given URL.
+ * The url is downloaded asynchronously using a CompletableFuture class.
+ * The Component is also using a "withFuture" dependency that allows to wait for the
+ * completion of the CompletableFuture, before registering the SiteInfo OSGi service.
+ */
+public class SiteInfoImpl implements SiteInfo {
+ final static String HREF_PATTERN = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
+ LogService m_log;
+ String m_url;
+ List<String> m_links; // List of hrefs contained in the web page referenced by m_url URL.
+
+
+ public SiteInfoImpl(String url) {
+ m_url = url;
+ }
+
+ void bind(LogService log) {
+ m_log = log;
+ }
+
+ void init(Component c) {
+ // Asynchronously calculate the number of links from the web site.
+ // We use Rx to define an asynchronous Observable task, and we wrap it to a CompletableFuture
+ // that is used as a Dependency Manager "Future" dependency, in order to block the activation of
+ // our component until the page has been downloaded and parsed.
+
+ Observable<List<String>> links = downloadSite(m_url)
+ .map(this::getSiteLinks);
+
+ component(c, comp -> comp
+ .withFuture(toFuture(links), futuredep -> futuredep.thenAccept(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 site=" + m_links.size());
+ }
+
+ @Override
+ public List<String> getLinks() {
+ return m_links;
+ }
+
+ private Observable<String> downloadSite(String url) {
+ return Observable.create(subscriber -> {
+ try (Scanner in = new Scanner(new URL(url).openStream())) {
+ StringBuilder builder = new StringBuilder();
+ while (in.hasNextLine()) {
+ builder.append(in.nextLine());
+ builder.append("\n");
+ }
+ subscriber.onNext(builder.toString());
+ } catch (IOException ex) {
+ RuntimeException rex = new RuntimeException();
+ rex.initCause(ex);
+ throw rex;
+ }
+ });
+ }
+
+ private List<String> getSiteLinks(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);
+ }
+
+ /**
+ * Converts {@link rx.Observable} to {@link java.util.concurrent.CompletableFuture}. Takes
+ * only the first value produced by observable.
+ *
+ * @param observable
+ * @param <T>
+ * @return
+ */
+ public static <T> CompletableFuture<T> toFuture(Observable<T> observable) {
+ return new ObservableCompletableFuture<T>(observable);
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/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/rx/observable/Activator.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/Activator.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/Activator.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,34 @@
+/*
+ * 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.dependencymanager.lambda.samples.rx.observable;
+
+import static java.lang.System.out;
+
+import org.apache.felix.dm.builder.lambda.DependencyActivatorBase;
+import org.osgi.service.log.LogService;
+
+public class Activator extends DependencyActivatorBase {
+
+ @Override
+ protected void init() throws Exception {
+ out.println("type \"log info\" to see the logs emitted by this test.");
+ component(comp -> comp.impl(ObservableComponent.class).withService(LogService.class));
+ }
+
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/ObservableComponent.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/rx/observable/ObservableComponent.java?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/ObservableComponent.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/ObservableComponent.java Sun Dec 13 22:23:57 2015
@@ -0,0 +1,85 @@
+/*
+ * 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.dependencymanager.lambda.samples.rx.observable;
+
+import static org.apache.felix.dm.builder.lambda.DependencyActivatorBase.component;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.log.LogService;
+
+import io.reactivex.Observable;
+import io.reactivex.internal.subscriptions.EmptySubscription;
+
+public class ObservableComponent {
+ DependencyManager m_dm; // injected
+ LogService m_log; // injected
+
+ public static class DocumentViewer {
+ final String m_title;
+ public DocumentViewer(String title) {
+ m_title = title;
+ }
+ void start() {
+ // Display the title in the GUI
+ }
+ }
+
+ // Returns a List of website URLs based on a text search
+ Observable<List<String>> query(String text) {
+ if (text.equals("rxjava")) {
+ return Observable.just(Arrays.asList("https://github.com/ReactiveX/RxJava", "https://en.wikipedia.org/wiki/Reactive_programming"));
+ } else {
+ return Observable.just(Collections.emptyList());
+ }
+ }
+
+ Observable<String> getTitle(String url) {
+ if (url.equals("https://github.com/ReactiveX/RxJava")) {
+ return Observable.just("ReactiveX/RxJava");
+ } else if (url.equals("https://en.wikipedia.org/wiki/Reactive_programming")) {
+ return Observable.just("Reactive Programming");
+ } else {
+ return Observable.just((String) null);
+ }
+ }
+
+ void start() {
+ m_log.log(LogService.LOG_INFO, "query ...");
+ query("rxjava")
+ .flatMap(urls -> Observable.fromStream(urls.stream()))
+ .flatMap(url -> getTitle(url))
+ .filter(title -> title != null)
+ .flatMap(title -> createObservableComponent(title))
+ .subscribe(component -> m_log.log(LogService.LOG_INFO, "Component started :" + component));
+ }
+
+ Observable<Component> createObservableComponent(String title) {
+ return Observable.create(publisher -> {
+ publisher.onSubscribe(EmptySubscription.INSTANCE);
+ component(m_dm, builder -> builder
+ .factory(() -> new DocumentViewer(title))
+ .onStart(publisher::onNext));
+ });
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/README
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/README?rev=1719841&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/README (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/rx/observable/README Sun Dec 13 22:23:57 2015
@@ -0,0 +1,32 @@
+The purpose of this sample is to experiment RxJava(2.0) and DependencyManager lambda; and to check if some hooks have
+to be added into DM-lambda in order to build some RxJava applications on top it.
+
+So, in this sample, A DM component is built from code (see ObservableComponent.java) using RxJava style.
+That is: using some Rx "Observables" and a chain of map() calls to build the DM component.
+
+So, basically, The sample first transforms a DM Component into an "Observable".
+Turning any object to an Rx Observable is easy, using the Observable<T>.create(Publisher publisher) method.
+For example:
+
+ Observable<Component> createObservableComponent(String componentParameters) {
+ return Observable.create(publisher -> {
+ publisher.onSubscribe(EmptySubscription.INSTANCE);
+ component(m_dm, builder -> builder
+ .factory(() -> new SomeDMComponent(componentParameters))
+ .onStart(publisher::onNext)); // will trigger next action in the map() chain only AFTER component is started.
+ });
+ }
+
+So, the component can then be created using a flow of map() transformations calls like in the following example:
+
+ query("rxjava") // returns Observable<List<String>> (list of URLs).
+ .flatMap(urls -> Observable.fromStream(urls.stream())) // Loop on each URL returned by the query
+ .flatMap(url -> getTitle(url)) // get the title of the current URL page content
+ .filter(title -> title != null) // Ignore page without title
+ .flatMap(title -> createObservableComponent(title)) // and create a component for the current title
+ .subscribe(component -> System.out.println("Component has started: " + component));
+
+The query(String search) returns an Observable<List<String>> representing the URLS in the web that match the given text search.
+The subscriber will be called only after the Component has been started, because the createObservableComponent method only calls
+the "publisher::onNext" method once the component is fully active (see "onStart(publisher::onNext))" call in the
+createObservableComponent function.
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/test/.gitignore
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/test/.gitignore?rev=1719841&view=auto
==============================================================================
(empty)
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/.classpath
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/.classpath?rev=1719841&view=auto
==============================================================================
Binary file - no diff available.
Propchange: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/.classpath
------------------------------------------------------------------------------
svn:mime-type = application/xml