reworked the sample in order to show a FactoryConfigurationAdapterService annotation usage example
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@947821 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/samples.annotation/README b/dependencymanager/samples.annotation/README
index 324098a..a8d97a4 100644
--- a/dependencymanager/samples.annotation/README
+++ b/dependencymanager/samples.annotation/README
@@ -3,17 +3,25 @@
Sample description:
This sample shows a basic "SpellChecker" application which provides a Felix "spellcheck" shell
- command. The SpellChecker class is a Felix Shell command (it provides the "Command" service),
+ command. The SpellChecker class is a Felix Shell command (it provides a "Command" service),
which accepts a string as parameter. So, when you type a string, the command just says if the
specified string has been found from one of its injected dictionaries. The SpellChecker class has a
- required/multiple dependency over any available DictionaryService. Currently, there is one
- "EnglishDictionary" which implements the DictionaryService. The EnglishDictionary service uses
- MetaType, allowing to configure english words through ConfigAdmin and WebConsole.
+ required/multiple (1..N) dependency over any available DictionaryService.
+
+ A DictionaryService is defined using a FactoryConfigurationAdapterService annotation, allowing to
+ instantiate many DictionaryService service instances from webconsole. This annotation actually registers
+ a ManagedServiceFactory into the Registry, and you can specify the meta type informations regarding
+ the properties metadata.
+
So, before testing, you first have to go to webconsole Configuration panel, and specify some
- english words in the configuration for the "English Dictionary" PID. Then, go to the felix shell,
- and you will then see the "spellcheck" command (when typing "help").
- Notice that in the sample, you will also find an Aspect Service (DictionaryAspect.java), which
- decorates the EnglishDictionary service, by adding an "aspect" word in the dictionary.
+ dictionaries (see the DictionaryService Factory PID).
+ Then, go to the felix shell, and you will then see the "spellcheck" command (when typing "help").
+
+ Notice that in the sample, you will also find a DictionaryAspect Service (DictionaryAspect.java), which
+ decorates the EnglishDictionary service, by adding some additional words to *all* provided
+ DictionaryService services. The DictionaryAspect also show how to use a ConfigurationDependency annotation,
+ allowing to configure the words from webconsole. A ConfigurationDependency actually registers a ManagedService object
+ in the Registry, which also implements a MetaTypeProvider service for metatype support.
How to test:
@@ -31,15 +39,16 @@
2) Start felix
3) Go to web console, in the Configuration pannel
- 4) Edit the "English Dictionary" Configuration, add some words, then click on "save".
- At this point, the "EnglishDictionary" service will be enabled and the SpellCheck component
- will be injected with it. Then you should see the "spellcheck" command, when typing "help" on the shell.
+ 4) Edit the "Dictionary Services" Configuration, add some dictionaries. By default, an English dictionary is
+ displayed. Just click on "save", then click on your refresh web browser: you will see a new dictionary service
+ instance. At this point, a DictionaryService service will be enabled (with the service property "lang=en"),
+ and the SpellCheck component will be injected with it. Then you should see the "spellcheck" command, when typing
+ "help" on the shell.
5) Just type "spellcheck hello", and the command should reply a fantastic message, like "word hello is correct".
-
-
-
-
-
-
+ 6) You can also click on the "Aspect Dictionary" button, in order to decorate *all* Dictionaries using some custom words.
+ By default, the "aspect" word is pre configured, but you can click on the "+" button in order to add more words.
+ Then click on Save. At this point, all DictionaryService instances will be decorated with the aspect service.
+ So, now, if you type "spellcheck aspect", then the message: "word aspect is correct" should be displayed.
+
diff --git a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryAspect.java b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryAspect.java
index 3eb2247..daa9f78 100644
--- a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryAspect.java
+++ b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryAspect.java
@@ -18,12 +18,18 @@
*/
package org.apache.felix.dm.samples.annotation;
+import java.util.Dictionary;
+import java.util.concurrent.CopyOnWriteArrayList;
+
import org.apache.felix.dm.annotation.api.AspectService;
+import org.apache.felix.dm.annotation.api.PropertyMetaData;
+import org.apache.felix.dm.annotation.api.dependency.ConfigurationDependency;
import org.apache.felix.dm.annotation.api.dependency.ServiceDependency;
import org.osgi.service.log.LogService;
/**
- * This aspect wraps a Dictionary and checks the "aspect" word on behalf of it.
+ * This aspect applies to all available Dictionary Services, and checks some custom words, configurable from
+ * config admin.
*/
@AspectService( ranking = 10 )
public class DictionaryAspect implements DictionaryService
@@ -34,15 +40,51 @@
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.
*/
@ServiceDependency(required = false)
private LogService m_log;
+ /**
+ * Defines a configuration dependency for retrieving our custo words (by default, our PID is our full class name).
+ * This annotation actually provides a ManagedService into the registry, and you can specify meta information regarding
+ * all the configuration properties (required by webconsole).
+ */
+ @ConfigurationDependency(
+ heading="Aspect Dictionary",
+ description="Declare here some words to check",
+ propagate=false,
+ metadata={
+ @PropertyMetaData(
+ heading="Dictionary aspect words",
+ description="Declare here the list of words supported by this dictionary aspect. ",
+ defaults={"aspect"},
+ id="words",
+ cardinality=Integer.MAX_VALUE)
+ }
+ )
+ protected void updated(Dictionary<String, ?> config) {
+ m_words.clear();
+ String[] words = (String[]) config.get("words");
+ for (String word : words) {
+ m_words.add(word);
+ }
+ }
+
+ /**
+ * 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_DEBUG, "DictionaryAspect: checking word " + word);
- if (word.equals("aspect")) {
+ if ("aspect".equals(word)) {
return true;
}
return m_originalDictionary.checkWord(word);
diff --git a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryImpl.java b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryImpl.java
new file mode 100644
index 0000000..449ee57
--- /dev/null
+++ b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/DictionaryImpl.java
@@ -0,0 +1,87 @@
+/*
+ * 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.samples.annotation;
+
+import java.util.Dictionary;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.felix.dm.annotation.api.PropertyMetaData;
+import org.apache.felix.dm.annotation.api.adapter.FactoryConfigurationAdapterService;
+
+/**
+ * A Dictionary Service. This service uses a FactoryConfigurationAdapterService annotation,
+ * allowing to instantiate this service from webconsole. This annotation will actually register
+ * a ManagedServiceFactory in the registry, and also support meta types for describing metadata of
+ * all configuration properties.
+ *
+ * You must configure at least one Dictionary from web console, since the SpellCheck won't start if no Dictionary
+ * Service is available.
+ */
+@FactoryConfigurationAdapterService(
+ factoryPid="DictionaryServiceFactory",
+ propagate=true,
+ updated="updated",
+ heading="Dictionary Services",
+ description="Declare here some Dictionary instances, allowing to instantiates some DictionaryService services for a given dictionary language",
+ metadata={
+ @PropertyMetaData(
+ heading="Dictionary Language",
+ description="Declare here the language supported by this dictionary. " +
+ "This property will be propagated with the Dictionary Service properties.",
+ defaults={"en"},
+ id="lang",
+ cardinality=1),
+ @PropertyMetaData(
+ heading="Dictionary words",
+ description="Declare here the list of words supported by this dictionary. " +
+ "This property is private and won't be propagated along with the dictionary service property.",
+ defaults={"hello", "world"},
+ id="words",
+ cardinality=Integer.MAX_VALUE)
+ }
+)
+public class DictionaryImpl implements DictionaryService
+{
+ /**
+ * 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>();
+
+ /**
+ * Our service will be initialized from ConfigAdmin, so we define here a configuration dependency
+ * (by default, our PID is our full class name).
+ * @param config The configuration where we'll lookup our words list (key="words").
+ */
+ protected void updated(Dictionary<String, ?> config) {
+ m_words.clear();
+ String[] words = (String[]) config.get("words");
+ for (String word : words) {
+ m_words.add(word);
+ }
+ }
+
+ /**
+ * 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);
+ }
+}
diff --git a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/EnglishDictionary.java b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/EnglishDictionary.java
deleted file mode 100644
index 3580bb1..0000000
--- a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/EnglishDictionary.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.samples.annotation;
-
-import java.util.Dictionary;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.felix.dm.annotation.api.dependency.ConfigurationDependency;
-import org.apache.felix.dm.annotation.api.Property;
-import org.apache.felix.dm.annotation.api.PropertyMetaData;
-import org.apache.felix.dm.annotation.api.Service;
-
-/**
- * An English Dictionary Service. We provide here our Properties MetaData in order to let webconsole configure us.
- * You must configure the PID that corresponds to this class through web console in order to activate this service.
- */
-@Service(properties={@Property(name="language", value="en")})
-public class EnglishDictionary implements DictionaryService
-{
- /**
- * The id of our Configuration Admin property key.
- */
- public 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>();
-
- /**
- * Our service will be initialized from ConfigAdmin, so we define here a configuration dependency
- * (by default, our PID is our full class name).
- * @param config The configuration where we'll lookup our words list (key="words").
- */
- @ConfigurationDependency(
- heading="English Dictionary",
- description = "Configuration for the EnglishDictionary Service",
- metadata={
- @PropertyMetaData(
- heading="English Words",
- description="Declare here some valid english words",
- defaults={"hello", "world"},
- id=EnglishDictionary.WORDS,
- cardinality=Integer.MAX_VALUE)
- }
- )
- protected void updated(Dictionary<String, ?> config) {
- m_words.clear();
- String[] words = (String[]) config.get(WORDS);
- for (String word : words) {
- m_words.add(word);
- }
- }
-
- /**
- * 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);
- }
-}
diff --git a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/SpellChecker.java b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/SpellChecker.java
index 0c50406..f962acf 100644
--- a/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/SpellChecker.java
+++ b/dependencymanager/samples.annotation/src/main/java/org/apache/felix/dm/samples/annotation/SpellChecker.java
@@ -22,9 +22,9 @@
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.felix.dm.annotation.api.Service;
-import org.apache.felix.dm.annotation.api.dependency.ServiceDependency;
import org.apache.felix.dm.annotation.api.Start;
import org.apache.felix.dm.annotation.api.Stop;
+import org.apache.felix.dm.annotation.api.dependency.ServiceDependency;
import org.apache.felix.shell.Command;
import org.osgi.service.log.LogService;