You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by bu...@apache.org on 2013/07/01 15:03:14 UTC

svn commit: r868027 - in /websites/staging/felix/trunk/content: ./ documentation/subprojects/apache-felix-config-admin.html

Author: buildbot
Date: Mon Jul  1 13:03:13 2013
New Revision: 868027

Log:
Staging update by buildbot for felix

Modified:
    websites/staging/felix/trunk/content/   (props changed)
    websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-config-admin.html

Propchange: websites/staging/felix/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Mon Jul  1 13:03:13 2013
@@ -1 +1 @@
-1498419
+1498422

Modified: websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-config-admin.html
==============================================================================
--- websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-config-admin.html (original)
+++ websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-config-admin.html Mon Jul  1 13:03:13 2013
@@ -18,7 +18,7 @@
     limitations under the License.
 -->
   <head>
-    <title>Apache Felix - Apache Felix Config Admin</title>
+    <title>Apache Felix - Apache Felix Configuration Admin Service</title>
     <link rel="icon" href="/res/favicon.ico">
     <link rel="stylesheet" href="/res/site.css" type="text/css" media="all">
     <link rel="stylesheet" href="/res/codehilite.css" type="text/css" media="all">
@@ -66,15 +66,9 @@
       </div>
 
       
-      <div class="tip">
-           This page is a translated version of <a href="/site/apache-felix-config-admin.html" target="felix_cwiki">/site/apache-felix-config-admin.html</a>. In case of
-           doubt you might want to refer to the old page.
-      </div>
-      
       
-      <h1>Apache Felix Config Admin</h1>
-      <h1 id="configuration-admin-service">Configuration Admin Service</h1>
-<p>The OSGi Componendium Configuration Admin Service specifies a service, which allows for easy management of configuration data for configurable components. Basicaly configuration is a list of name-value pairs. Configuration is managed by management applications by asking the Configuration Admin Service for such configuration. After updating the configuration, it is sent back to the Configuration Admin Service. The Configuration Admin Service is like a central hub, which cares for persisting this configuration and also for distributing the configuration to interested parties. One class of such parties are the components to be configured. These are registered as <code>ManagedService</code> services. There is also a notion of <code>ManagedServiceFactory</code>, which allows for multiple configurations of the same kind to be applied.</p>
+      <h1>Apache Felix Configuration Admin Service</h1>
+      <p>The OSGi Componendium Configuration Admin Service specifies a service, which allows for easy management of configuration data for configurable components. Basicaly configuration is a list of name-value pairs. Configuration is managed by management applications by asking the Configuration Admin Service for such configuration. After updating the configuration, it is sent back to the Configuration Admin Service. The Configuration Admin Service is like a central hub, which cares for persisting this configuration and also for distributing the configuration to interested parties. One class of such parties are the components to be configured. These are registered as <code>ManagedService</code> services. There is also a notion of <code>ManagedServiceFactory</code>, which allows for multiple configurations of the same kind to be applied.</p>
 <p>For more information, I suggest you read Chapter 104, Configuration Admin Service Specification, of the OSGi Compendium Services Specification book. IMHO this is worth reading.</p>
 <p>For a starter this page sets out to describe how you can create a component, which is interested in some configuration. As such this page is at its very beginning just highlighting the simplest of all cases: A single component being interested in its configuration.</p>
 <h2 id="managedservice-example"><code>ManagedService</code> Example</h2>
@@ -87,202 +81,220 @@
 </ul>
 <p>The PID is just a string, which must be globally unique. Assuming a simple case where your PrettyPrinter configurator receives the configuration has a unique class name, you may well use that name. So lets assume, our <code>ManagedService</code> is called <code>org.sample.PrettyPrinterConfigurator</code> and that name is also used as the PID. For more information on the Service PID, refer to Section 104.3, The Persistent Identity of the OSGi Compendium Services Specification.</p>
 <p>The class would be:</p>
-<DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>PrettyPrinterConfigurator.java</B></DIV><DIV class="codeContent panelContent">
-       package org.sample;
-       class PrettyPrinterConfigurator implements ManagedService {
-           public void update(Dictionary props)
-               throws ConfigurationException {
-               if (props == null) {
-                   // no configuration from configuration admin
-                   // or old configuration has been deleted
-               } else {
-                   // apply configuration from config admin
-               }
-           }
-       }
-
-Now, in your bundle activator's start() method you register the `PrettyPrinterConfigurator` as a `ManagedService`:
-
-<DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>PrettyPrinterActivator.java</B></DIV><DIV class="codeContent panelContent">
-    ...
-    private ServiceRegistration ppcService;
-    public void start(BundleContext context) {
-        Dictionary props = new Hashtable();
-        props.put("service.pid", "org.sample.PrettyPrinterConfigurator");
-        ppcService = context.registerService(ManagedService.class.getName(),
-            new PrettyPrinterConfigurator(), props);
-    }
-    public void stop(BundleContext context) {
-        if (ppcService != null) {
-            ppcService.unregister();
-            ppcService = null;
-        }
-    }
-    ...
-
-
-That's more or less it. You may now go on to use your favourite tool to create and edit the configuration for the `PrettyPrinterConfigurator`, for example something like this:
-
-
-    Configuration config = configurationAdmin.getConfiguration(
-        "org.sample.PrettyPrinterConfigurator");
-    Dictionary props = config.getProperties();
-
-    // if null, the configuration is new
-    if (props == null) {
-        props = new Hashtable();
-    }
-
-    // set some properties
-    props.put(..., ...);
-
-    // update the configuration
-    config.update(props);
-
-
-After the call to `update` the Configuration Admin service persists the new configuration data and sends an update to the `ManagedService` registered with the service PID `org.sample.PrettyPrinterConfigurator`, which happens to be our `PrettyPrinterConfigurator` class as expected.
-
-
-## ManagedServiceFactory example
-
-Registering a service as ManagedServiceFactory means that it will be able to receive several different configuration dictionaries; that's particularly useful when we want to create a Service Factory, that is, a service responsible for creating multiple instances of a specific service.
-
-A ManagedServiceFactory service needs to implement the ManagedServiceFactory interface, as showed in the example.
-
-
-    public class SmsSenderFactory implements ManagedServiceFactory
-    {   
-        Map existingServices = new HashMap();
-
-        public void updated(String pid, Dictionary dictionary) throws ConfigurationException 
-        {
-            // invoked when a new configuration dictionary is assigned
-            // to service 'pid'. 
-            if (existingServices.containsKey(pid))  //the service already exists
-            {
-                MyService service = (MyService) existingServices.get(pid);
-                service.configure(dictionary);
-            }
-            else //configuration dictionary for a new service
-            {
-                MyService service = createNewServiceInstance();
-                service.configure(dictionary);
-                existingServices.put(pid, service);
-            }
-        }
-
-        public void deleted(String pid) 
-        {
-            // invoked when the service 'pid' is deleted
-            existingServices.remove(pid);
-        }
-
-        public String getName() 
-        {
-            return "test.smssenderfactory";
-        }
-    }
-
-
-The example above shows that, differently from the ManagedService, the ManagedServiceFactory is designed to manage multiple instances of a service. In fact, the `update` method accept a `pid` and a `Dictionary` as arguments, thus allowing to associate a certain configuration dictionary to a particular service instance (identified by the `pid`).
-
-Note also that the ManagedServiceFactory interface requires to implement (besides the `getName` method) a `delete` method: this method is invoked when the Configuration Admin Service asks the ManagedServiceFactory to delete a specific service instance.
-
-The registration of a `ManagedServiceFactory` follows the same steps of the `ManagedService` example:
-
-
-    private ServiceRegistration factoryService;
-    public void start(BundleContext context) {
-        Dictionary props = new Hashtable();
-        props.put("service.pid", "test.smssenderfactory");
-        factoryService = context.registerService(ManagedServiceFactory.class.getName(),
-            new SmsSenderFactory(), props);
-    }
-    public void stop(BundleContext context) {
-        if (factoryService != null) {
-            factoryService.unregister();
-            factoryService = null;
-        }
-    }
-    ...
-
-
-Finally, using the ConfigurationAdmin interface, it is possible to send new or updated configuration dictionaries to the newly created ManagedServiceFactory:
-
-
-    public class Activator implements BundleActivator 
-    {   
-        private List configurationList = new ArrayList();  
-
-        public void start(BundleContext bundleContext) throws Exception 
-        {  
-            ServiceReference configurationAdminReference = 
-                bundleContext.getServiceReference(ConfigurationAdmin.class.getName());  
-
-            if (configurationAdminReference != null) 
-            {  
-                ConfigurationAdmin confAdmin = (ConfigurationAdmin) bundleContext.getService(configurationAdminReference);  
-
-                Configuration configuration = confAdmin.createFactoryConfiguration("test.smssenderfactory", null);  
-                Dictionary properties = createServiceProperties();
-                configuration.update(properties);  
-
-                //Store in the configurationList the configuration object, the dictionary object
-                //or configuration.getPid()  for future use  
-                configurationList.add(configuration);  
-            }  
-        }   
-    }  
-
-
-
-## Apache Felix Implementation Details
-
-The Apache Felix implementation of the Configuration Admin Service specification has a few specialities, which may be of interest when deploying it. These are described here.
-
-
-### Configuration Properties
-
-The Apache Felix implementation is configurable with Framework properties. Here is a short table listing the properties. Please refer to the later sections for a description of these properties.
-
-| Property | Type | Default Value | Description |
-|--|--|--|--|
-| `felix.cm.loglevel` | int | `2` | Logging level to use in the absence of an OSGi LogService. See the *Logging* section below. |
-| `felix.cm.dir` | String | `BundleContext.getDataFile("config")` | Location of the Configuration Admin configuration files. See the *Configuration Files* section below. |
-
-### Logging
-
-Logging goes to the OSGi LogService if such a service is registered int the OSGi framework. If no OSGi LogService is registered, the log output is directed to the Java platform standard error output (`System.err`).
-
-To limit the output in the absence of an OSGi LogService, the `felix.cm.loglevel` framework property may be set to an integer value limiting the level of the log messages actually written: Only messages whose level is lower than or equal to the limit is actually written. All other messages are discarded.
-
-The log levels correspond to the predefined log levels of the OSGi Log Service Specification as listed in the following table:
-
-| Level Number | LogService Constant | Remark |
-|--|--|--|
-| 1 | LOG_ERROR | Used for error messages |
-| 2 | LOG_WARNING | Used for warning messages. This is the default value of the `felix.cm.loglevel` property if it is not set or if the value cannot be converted to an integer. |
-| 3 | LOG_INFO | Used for informational messages |
-| 4 | LOG_DEBUG | Used for debug messages |
-
-*Note*: The `felix.cm.loglevel` property is ignored if an OSGi LogService is actually used for logging because it is then the responsibility of the LogService to limit the actual log output.
-
-
-### Configuration Files
-
-By default the Apache Felix Configuration Admin Implementation stores the configuration data in the platform filesystem. The location of the configuration data can be configured with the `felix.cm.dir` framework property.
-
-The resolution of the location using the `felix.cm.dir` and the `BundleContext` is implemented according to the following algorithm.
-
-1. If the `felix.cm.dir` property is not set, a directory named `config` is used inside the persistent storage area of the Apache Felix Configuration Admin Service bundle is used. This is the default behaviour.
-1. If the `felix.cm.dir` property is not set and the framework does not support persistent storage area for bundles in the filesystem, the `config` directory is used in the current working directory as specified in the `user.dir` system property is assumed.
-1. Otherwise the `felix.cm.dir` property value is used as the directory name to take the configuration data.
-
-The result of these steps may be a relative file. In this case and if the framework provides access to persistent storage area, the directory name is resolved as being inside the persistent storage area. Otherwise the directory name is resolved to an absolute path calling the File.getAbsoluteFile() method.
-
-If a non-directory file exists as the location found in the previous step or the named directory (including any parent directories) cannot be created, the configuration data cannot be stored in the filesystem. Generally this will result in failure to store configuration data at all, except if there is a `org.apache.felix.cm.PersistenceManager` service registered, which is then used.
+<div class="codehilite"><pre>   <span class="n">package</span> <span class="n">org</span><span class="p">.</span><span class="n">sample</span><span class="p">;</span>
+   <span class="n">class</span> <span class="n">PrettyPrinterConfigurator</span> <span class="n">implements</span> <span class="n">ManagedService</span> <span class="p">{</span>
+       <span class="n">public</span> <span class="n">void</span> <span class="n">update</span><span class="p">(</span><span class="n">Dictionary</span> <span class="n">props</span><span class="p">)</span>
+           <span class="n">throws</span> <span class="n">ConfigurationException</span> <span class="p">{</span>
+           <span class="k">if</span> <span class="p">(</span><span class="n">props</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+               <span class="o">//</span> <span class="n">no</span> <span class="n">configuration</span> <span class="n">from</span> <span class="n">configuration</span> <span class="n">admin</span>
+               <span class="o">//</span> <span class="n">or</span> <span class="n">old</span> <span class="n">configuration</span> <span class="n">has</span> <span class="n">been</span> <span class="n">deleted</span>
+           <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+               <span class="o">//</span> <span class="n">apply</span> <span class="n">configuration</span> <span class="n">from</span> <span class="n">config</span> <span class="n">admin</span>
+           <span class="p">}</span>
+       <span class="p">}</span>
+   <span class="p">}</span>
+</pre></div>
+
+
+<p>Now, in your bundle activator's start() method you register the <code>PrettyPrinterConfigurator</code> as a <code>ManagedService</code>:</p>
+<div class="codehilite"><pre><span class="p">...</span>
+<span class="n">private</span> <span class="n">ServiceRegistration</span> <span class="n">ppcService</span><span class="p">;</span>
+<span class="n">public</span> <span class="n">void</span> <span class="n">start</span><span class="p">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">Dictionary</span> <span class="n">props</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Hashtable</span><span class="p">();</span>
+    <span class="n">props</span><span class="p">.</span><span class="n">put</span><span class="p">(</span>&quot;<span class="n">service</span><span class="p">.</span><span class="n">pid</span>&quot;<span class="p">,</span> &quot;<span class="n">org</span><span class="p">.</span><span class="n">sample</span><span class="p">.</span><span class="n">PrettyPrinterConfigurator</span>&quot;<span class="p">);</span>
+    <span class="n">ppcService</span> <span class="p">=</span> <span class="n">context</span><span class="p">.</span><span class="n">registerService</span><span class="p">(</span><span class="n">ManagedService</span><span class="p">.</span><span class="n">class</span><span class="p">.</span><span class="n">getName</span><span class="p">(),</span>
+        <span class="n">new</span> <span class="n">PrettyPrinterConfigurator</span><span class="p">(),</span> <span class="n">props</span><span class="p">);</span>
+<span class="p">}</span>
+<span class="n">public</span> <span class="n">void</span> <span class="n">stop</span><span class="p">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="p">)</span> <span class="p">{</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">ppcService</span> !<span class="p">=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">ppcService</span><span class="p">.</span><span class="n">unregister</span><span class="p">();</span>
+        <span class="n">ppcService</span> <span class="p">=</span> <span class="n">null</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+<span class="p">...</span>
+</pre></div>
+
+
+<p>That's more or less it. You may now go on to use your favourite tool to create and edit the configuration for the <code>PrettyPrinterConfigurator</code>, for example something like this:</p>
+<div class="codehilite"><pre><span class="n">Configuration</span> <span class="n">config</span> <span class="p">=</span> <span class="n">configurationAdmin</span><span class="p">.</span><span class="n">getConfiguration</span><span class="p">(</span>
+    &quot;<span class="n">org</span><span class="p">.</span><span class="n">sample</span><span class="p">.</span><span class="n">PrettyPrinterConfigurator</span>&quot;<span class="p">);</span>
+<span class="n">Dictionary</span> <span class="n">props</span> <span class="p">=</span> <span class="n">config</span><span class="p">.</span><span class="n">getProperties</span><span class="p">();</span>
+
+<span class="o">//</span> <span class="k">if</span> <span class="n">null</span><span class="p">,</span> <span class="n">the</span> <span class="n">configuration</span> <span class="n">is</span> <span class="n">new</span>
+<span class="k">if</span> <span class="p">(</span><span class="n">props</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">props</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Hashtable</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="o">//</span> <span class="n">set</span> <span class="n">some</span> <span class="k">properties</span>
+<span class="n">props</span><span class="p">.</span><span class="n">put</span><span class="p">(...,</span> <span class="p">...);</span>
+
+<span class="o">//</span> <span class="n">update</span> <span class="n">the</span> <span class="n">configuration</span>
+<span class="n">config</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">props</span><span class="p">);</span>
+</pre></div>
+
+
+<p>After the call to <code>update</code> the Configuration Admin service persists the new configuration data and sends an update to the <code>ManagedService</code> registered with the service PID <code>org.sample.PrettyPrinterConfigurator</code>, which happens to be our <code>PrettyPrinterConfigurator</code> class as expected.</p>
+<h2 id="managedservicefactory-example">ManagedServiceFactory example</h2>
+<p>Registering a service as ManagedServiceFactory means that it will be able to receive several different configuration dictionaries; that's particularly useful when we want to create a Service Factory, that is, a service responsible for creating multiple instances of a specific service.</p>
+<p>A ManagedServiceFactory service needs to implement the ManagedServiceFactory interface, as showed in the example.</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">SmsSenderFactory</span> <span class="n">implements</span> <span class="n">ManagedServiceFactory</span>
+<span class="p">{</span>   
+    <span class="n">Map</span> <span class="n">existingServices</span> <span class="p">=</span> <span class="n">new</span> <span class="n">HashMap</span><span class="p">();</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">updated</span><span class="p">(</span><span class="n">String</span> <span class="n">pid</span><span class="p">,</span> <span class="n">Dictionary</span> <span class="n">dictionary</span><span class="p">)</span> <span class="n">throws</span> <span class="n">ConfigurationException</span> 
+    <span class="p">{</span>
+        <span class="o">//</span> <span class="n">invoked</span> <span class="n">when</span> <span class="n">a</span> <span class="n">new</span> <span class="n">configuration</span> <span class="n">dictionary</span> <span class="n">is</span> <span class="n">assigned</span>
+        <span class="o">//</span> <span class="n">to</span> <span class="n">service</span> <span class="s">&#39;pid&#39;</span><span class="p">.</span> 
+        <span class="k">if</span> <span class="p">(</span><span class="n">existingServices</span><span class="p">.</span><span class="n">containsKey</span><span class="p">(</span><span class="n">pid</span><span class="p">))</span>  <span class="o">//</span><span class="n">the</span> <span class="n">service</span> <span class="n">already</span> <span class="n">exists</span>
+        <span class="p">{</span>
+            <span class="n">MyService</span> <span class="n">service</span> <span class="p">=</span> <span class="p">(</span><span class="n">MyService</span><span class="p">)</span> <span class="n">existingServices</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">pid</span><span class="p">);</span>
+            <span class="n">service</span><span class="p">.</span><span class="n">configure</span><span class="p">(</span><span class="n">dictionary</span><span class="p">);</span>
+        <span class="p">}</span>
+        <span class="k">else</span> <span class="o">//</span><span class="n">configuration</span> <span class="n">dictionary</span> <span class="k">for</span> <span class="n">a</span> <span class="n">new</span> <span class="n">service</span>
+        <span class="p">{</span>
+            <span class="n">MyService</span> <span class="n">service</span> <span class="p">=</span> <span class="n">createNewServiceInstance</span><span class="p">();</span>
+            <span class="n">service</span><span class="p">.</span><span class="n">configure</span><span class="p">(</span><span class="n">dictionary</span><span class="p">);</span>
+            <span class="n">existingServices</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="n">pid</span><span class="p">,</span> <span class="n">service</span><span class="p">);</span>
+        <span class="p">}</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">deleted</span><span class="p">(</span><span class="n">String</span> <span class="n">pid</span><span class="p">)</span> 
+    <span class="p">{</span>
+        <span class="o">//</span> <span class="n">invoked</span> <span class="n">when</span> <span class="n">the</span> <span class="n">service</span> <span class="s">&#39;pid&#39;</span> <span class="n">is</span> <span class="n">deleted</span>
+        <span class="n">existingServices</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="n">pid</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">String</span> <span class="n">getName</span><span class="p">()</span> 
+    <span class="p">{</span>
+        <span class="k">return</span> &quot;<span class="n">test</span><span class="p">.</span><span class="n">smssenderfactory</span>&quot;<span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>The example above shows that, differently from the ManagedService, the ManagedServiceFactory is designed to manage multiple instances of a service. In fact, the <code>update</code> method accept a <code>pid</code> and a <code>Dictionary</code> as arguments, thus allowing to associate a certain configuration dictionary to a particular service instance (identified by the <code>pid</code>).</p>
+<p>Note also that the ManagedServiceFactory interface requires to implement (besides the <code>getName</code> method) a <code>delete</code> method: this method is invoked when the Configuration Admin Service asks the ManagedServiceFactory to delete a specific service instance.</p>
+<p>The registration of a <code>ManagedServiceFactory</code> follows the same steps of the <code>ManagedService</code> example:</p>
+<div class="codehilite"><pre><span class="n">private</span> <span class="n">ServiceRegistration</span> <span class="n">factoryService</span><span class="p">;</span>
+<span class="n">public</span> <span class="n">void</span> <span class="n">start</span><span class="p">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">Dictionary</span> <span class="n">props</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Hashtable</span><span class="p">();</span>
+    <span class="n">props</span><span class="p">.</span><span class="n">put</span><span class="p">(</span>&quot;<span class="n">service</span><span class="p">.</span><span class="n">pid</span>&quot;<span class="p">,</span> &quot;<span class="n">test</span><span class="p">.</span><span class="n">smssenderfactory</span>&quot;<span class="p">);</span>
+    <span class="n">factoryService</span> <span class="p">=</span> <span class="n">context</span><span class="p">.</span><span class="n">registerService</span><span class="p">(</span><span class="n">ManagedServiceFactory</span><span class="p">.</span><span class="n">class</span><span class="p">.</span><span class="n">getName</span><span class="p">(),</span>
+        <span class="n">new</span> <span class="n">SmsSenderFactory</span><span class="p">(),</span> <span class="n">props</span><span class="p">);</span>
+<span class="p">}</span>
+<span class="n">public</span> <span class="n">void</span> <span class="n">stop</span><span class="p">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="p">)</span> <span class="p">{</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">factoryService</span> !<span class="p">=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">factoryService</span><span class="p">.</span><span class="n">unregister</span><span class="p">();</span>
+        <span class="n">factoryService</span> <span class="p">=</span> <span class="n">null</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+<span class="p">...</span>
+</pre></div>
+
+
+<p>Finally, using the ConfigurationAdmin interface, it is possible to send new or updated configuration dictionaries to the newly created ManagedServiceFactory:</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">Activator</span> <span class="n">implements</span> <span class="n">BundleActivator</span> 
+<span class="p">{</span>   
+    <span class="n">private</span> <span class="n">List</span> <span class="n">configurationList</span> <span class="p">=</span> <span class="n">new</span> <span class="n">ArrayList</span><span class="p">();</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">start</span><span class="p">(</span><span class="n">BundleContext</span> <span class="n">bundleContext</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> 
+    <span class="p">{</span>  
+        <span class="n">ServiceReference</span> <span class="n">configurationAdminReference</span> <span class="p">=</span> 
+            <span class="n">bundleContext</span><span class="p">.</span><span class="n">getServiceReference</span><span class="p">(</span><span class="n">ConfigurationAdmin</span><span class="p">.</span><span class="n">class</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+
+        <span class="k">if</span> <span class="p">(</span><span class="n">configurationAdminReference</span> !<span class="p">=</span> <span class="n">null</span><span class="p">)</span> 
+        <span class="p">{</span>  
+            <span class="n">ConfigurationAdmin</span> <span class="n">confAdmin</span> <span class="p">=</span> <span class="p">(</span><span class="n">ConfigurationAdmin</span><span class="p">)</span> <span class="n">bundleContext</span><span class="p">.</span><span class="n">getService</span><span class="p">(</span><span class="n">configurationAdminReference</span><span class="p">);</span>
+
+            <span class="n">Configuration</span> <span class="n">configuration</span> <span class="p">=</span> <span class="n">confAdmin</span><span class="p">.</span><span class="n">createFactoryConfiguration</span><span class="p">(</span>&quot;<span class="n">test</span><span class="p">.</span><span class="n">smssenderfactory</span>&quot;<span class="p">,</span> <span class="n">null</span><span class="p">);</span>  
+            <span class="n">Dictionary</span> <span class="k">properties</span> <span class="p">=</span> <span class="n">createServiceProperties</span><span class="p">();</span>
+            <span class="n">configuration</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="k">properties</span><span class="p">);</span>
+
+            <span class="o">//</span><span class="n">Store</span> <span class="n">in</span> <span class="n">the</span> <span class="n">configurationList</span> <span class="n">the</span> <span class="n">configuration</span> <span class="n">object</span><span class="p">,</span> <span class="n">the</span> <span class="n">dictionary</span> <span class="n">object</span>
+            <span class="o">//</span><span class="n">or</span> <span class="n">configuration</span><span class="p">.</span><span class="n">getPid</span><span class="p">()</span>  <span class="k">for</span> <span class="n">future</span> <span class="n">use</span>  
+            <span class="n">configurationList</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">configuration</span><span class="p">);</span>  
+        <span class="p">}</span>  
+    <span class="p">}</span>   
+<span class="p">}</span>
+</pre></div>
+
+
+<h2 id="apache-felix-implementation-details">Apache Felix Implementation Details</h2>
+<p>The Apache Felix implementation of the Configuration Admin Service specification has a few specialities, which may be of interest when deploying it. These are described here.</p>
+<h3 id="configuration-properties">Configuration Properties</h3>
+<p>The Apache Felix implementation is configurable with Framework properties. Here is a short table listing the properties. Please refer to the later sections for a description of these properties.</p>
+<table>
+<thead>
+<tr>
+<th>Property</th>
+<th>Type</th>
+<th>Default Value</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>felix.cm.loglevel</code></td>
+<td>int</td>
+<td><code>2</code></td>
+<td>Logging level to use in the absence of an OSGi LogService. See the <em>Logging</em> section below.</td>
+</tr>
+<tr>
+<td><code>felix.cm.dir</code></td>
+<td>String</td>
+<td><code>BundleContext.getDataFile("config")</code></td>
+<td>Location of the Configuration Admin configuration files. See the <em>Configuration Files</em> section below.</td>
+</tr>
+</tbody>
+</table>
+<h3 id="logging">Logging</h3>
+<p>Logging goes to the OSGi LogService if such a service is registered int the OSGi framework. If no OSGi LogService is registered, the log output is directed to the Java platform standard error output (<code>System.err</code>).</p>
+<p>To limit the output in the absence of an OSGi LogService, the <code>felix.cm.loglevel</code> framework property may be set to an integer value limiting the level of the log messages actually written: Only messages whose level is lower than or equal to the limit is actually written. All other messages are discarded.</p>
+<p>The log levels correspond to the predefined log levels of the OSGi Log Service Specification as listed in the following table:</p>
+<table>
+<thead>
+<tr>
+<th>Level Number</th>
+<th>LogService Constant</th>
+<th>Remark</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>1</td>
+<td>LOG_ERROR</td>
+<td>Used for error messages</td>
+</tr>
+<tr>
+<td>2</td>
+<td>LOG_WARNING</td>
+<td>Used for warning messages. This is the default value of the <code>felix.cm.loglevel</code> property if it is not set or if the value cannot be converted to an integer.</td>
+</tr>
+<tr>
+<td>3</td>
+<td>LOG_INFO</td>
+<td>Used for informational messages</td>
+</tr>
+<tr>
+<td>4</td>
+<td>LOG_DEBUG</td>
+<td>Used for debug messages</td>
+</tr>
+</tbody>
+</table>
+<p><em>Note</em>: The <code>felix.cm.loglevel</code> property is ignored if an OSGi LogService is actually used for logging because it is then the responsibility of the LogService to limit the actual log output.</p>
+<h3 id="configuration-files">Configuration Files</h3>
+<p>By default the Apache Felix Configuration Admin Implementation stores the configuration data in the platform filesystem. The location of the configuration data can be configured with the <code>felix.cm.dir</code> framework property.</p>
+<p>The resolution of the location using the <code>felix.cm.dir</code> and the <code>BundleContext</code> is implemented according to the following algorithm.</p>
+<ol>
+<li>If the <code>felix.cm.dir</code> property is not set, a directory named <code>config</code> is used inside the persistent storage area of the Apache Felix Configuration Admin Service bundle is used. This is the default behaviour.</li>
+<li>If the <code>felix.cm.dir</code> property is not set and the framework does not support persistent storage area for bundles in the filesystem, the <code>config</code> directory is used in the current working directory as specified in the <code>user.dir</code> system property is assumed.</li>
+<li>Otherwise the <code>felix.cm.dir</code> property value is used as the directory name to take the configuration data.</li>
+</ol>
+<p>The result of these steps may be a relative file. In this case and if the framework provides access to persistent storage area, the directory name is resolved as being inside the persistent storage area. Otherwise the directory name is resolved to an absolute path calling the File.getAbsoluteFile() method.</p>
+<p>If a non-directory file exists as the location found in the previous step or the named directory (including any parent directories) cannot be created, the configuration data cannot be stored in the filesystem. Generally this will result in failure to store configuration data at all, except if there is a <code>org.apache.felix.cm.PersistenceManager</code> service registered, which is then used.</p>
       <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
-        Rev. 1422427 by fmeschbe on Sun, 16 Dec 2012 00:36:51 +0000
+        Rev. 1498422 by fmeschbe on Mon, 1 Jul 2013 13:03:05 +0000
       </div>
       <div class="trademarkFooter"> 
         Apache Felix, Felix, Apache, the Apache feather logo, and the Apache Felix project