Author: buildbot
Date: Wed Feb 24 09:27:24 2016
New Revision: 981063
Log:
Staging update by buildbot for felix
Modified:
websites/staging/felix/trunk/content/ (props changed)
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/dependency-configuration.html
Propchange: websites/staging/felix/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Feb 24 09:27:24 2016
@@ -1 +1 @@
-1732042
+1732044
Modified:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/dependency-configuration.html
==============================================================================
---
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/dependency-configuration.html
(original)
+++
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/dependency-configuration.html
Wed Feb 24 09:27:24 2016
@@ -89,21 +89,88 @@ h2:hover > .headerlink, h3:hover > .head
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink,
h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink,
dt:hover > .elementid-permalink { visibility: visible }</style>
<p>A configuration dependency is always required, and allows you to depend on
the availability of a valid configuration for your component. Optional
configuration dependencies are not supported because in that case you can just
as well register as a <code>ManagedService</code> yourself.</p>
+<p>The dependency injects by default the configuration in an "updated"
callback which can accept the following parameters:</p>
+<ul>
+<li>updated(Dictionary)</li>
+<li>updated(Component, Dictionary)</li>
+<li>updated(ConfigurationType)</li>
+<li>updated(Component, ConfigurationType)</li>
+</ul>
+<p>If you only specify a pid, by default the callback method name is assumed
to be "updated".</p>
+<p>Configuration types are a new feature that allows you to specify an
interface that is implemented by DM and such interface is then injected to your
callback instead of the actual Dictionary. Using such configuration interface
provides a way for creating type-safe configurations from a actual Dictionary
that is normally injected by Dependency Manager. The callback accepts in
argument an interface that you have to provide, and DM will inject a proxy that
converts method calls from your configuration-type to lookups in the actual map
or dictionary. The results of these lookups are then converted to the expected
return type of the invoked configuration method.
+As proxies are injected, no implementations of the desired configuration-type
are necessary!</p>
+<p>The lookups performed are based on the name of the method called on the
configuration type. The method names are "mangled" to the following form:
[lower case letter] [any valid character]*. Method names starting with get or
is (JavaBean convention) are stripped from these prefixes. For example: given a
dictionary with the key "foo" can be accessed from a configuration-type using
the following method names: foo(), getFoo() and isFoo().</p>
+<p>The return values supported are: primitive types (or their object
wrappers), strings, enums, arrays of primitives/strings, Collection types, Map
types, Classes and interfaces. When an interface is returned, it is treated
equally to a configuration type, that is, it is returned as a proxy.</p>
+<p>Arrays can be represented either as comma-separated values, optionally
enclosed in square brackets. For example: [ a, b, c ] and a, b,c are both
considered an array of length 3 with the values "a", "b" and "c".
Alternatively, you can append the array index to the key in the dictionary to
obtain the same: a dictionary with "arr.0" => "a", "arr.1" => "b",
"arr.2" => "c" would result in the same array as the earlier examples.</p>
+<p>Maps can be represented as single string values similarly as arrays, each
value consisting of both the key and value separated by a dot. Optionally, the
value can be enclosed in curly brackets. Similar to array, you can use the same
dot notation using the keys. For example, a dictionary with</p>
+<p>"map" => "{key1.value1, key2.value2}"</p>
+<p>and a dictionary with</p>
+<p>"map.key1" => "value1", "map2.key2" => "value2"</p>
+<p>result in the same map being returned. Instead of a map, you could also
define an interface with the methods getKey1() and getKey2 and use that
interface as return type instead of a Map.</p>
+<p>In case a lookup does not yield a value from the underlying map or
dictionary, the following rules are applied:</p>
+<ul>
+<li>primitive types yield their default value, as defined by the Java
Specification;</li>
+<li>string, Classes and enum values yield null;</li>
+<li>for arrays, collections and maps, an empty array/collection/map is
returned;</li>
+<li>for other interface types that are treated as configuration type a
null-object is returned. </li>
+</ul>
+<p>Usage example where a component depends on a configuration:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">ServiceImpl</span> <span
class="o">{</span>
+ <span class="kt">void</span> <span class="nf">modified</span><span
class="o">(</span><span class="n">Dictionary</span><span
class="o"><</span><span class="n">String</span><span class="o">,</span>
<span class="n">Object</span><span class="o">></span> <span
class="n">cnf</span><span class="o">)</span> <span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span><span
class="n">cnf</span> <span class="o">!=</span> <span
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+ <span class="n">String</span> <span class="n">addr</span> <span
class="o">=</span> <span class="o">(</span><span class="n">String</span><span
class="o">)</span> <span class="n">cnf</span><span class="o">.</span><span
class="na">get</span><span class="o">(</span><span
class="s">"address"</span><span class="o">);</span>
+ <span class="kt">int</span> <span class="n">port</span> <span
class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span
class="na">valueOf</span><span class="o">(</span><span
class="n">cnf</span><span class="o">.</span><span class="na">get</span><span
class="o">(</span><span class="s">"port"</span><span
class="o">);</span>
+ <span class="o">...</span>
+ <span class="o">}</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span
class="nc">Activator</span> <span class="kd">extends</span> <span
class="n">DependencyActivatorBase</span> <span class="o">{</span>
+ <span class="nd">@Override</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">init</span><span class="o">(</span><span
class="n">BundleContext</span> <span class="n">ctx</span><span
class="o">,</span> <span class="n">DependencyManager</span> <span
class="n">dm</span><span class="o">)</span> <span class="kd">throws</span>
<span class="n">Exception</span> <span class="o">{</span>
+ <span class="n">dm</span><span class="o">.</span><span
class="na">add</span><span class="o">(</span><span
class="n">createComponent</span><span class="o">()</span>
+ <span class="o">.</span><span
class="na">setImplementation</span><span class="o">(</span><span
class="n">ServiceImpl</span><span class="o">.</span><span
class="na">class</span><span class="o">)</span>
+ <span class="o">.</span><span class="na">add</span><span
class="o">(</span><span class="n">createConfigurationDependency</span><span
class="o">().</span><span class="na">setPid</span><span class="o">(</span><span
class="n">ServiceImpl</span><span class="o">.</span><span
class="na">class</span><span class="o">.</span><span
class="na">getName</span><span class="o">()));</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Here is the same example, but a custom configuration type interface is used
(by default, the fqdn of the configuration type is assumed to be the
configuration pid):</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span
class="kd">interface</span> <span class="nc">MyConfig</span> <span
class="o">{</span>
+ <span class="n">String</span> <span class="nf">getAddress</span><span
class="o">();</span>
+ <span class="kt">int</span> <span class="nf">getPort</span><span
class="o">();</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span
class="nc">ServiceImpl</span> <span class="o">{</span>
+ <span class="kt">void</span> <span class="nf">modified</span><span
class="o">(</span><span class="n">MyConfig</span> <span
class="n">cnf</span><span class="o">)</span> <span class="o">{</span>
+ <span class="k">if</span> <span class="o">(</span><span
class="n">cnf</span> <span class="o">!=</span> <span
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+ <span class="n">String</span> <span class="n">addr</span> <span
class="o">=</span> <span class="n">cnf</span><span class="o">.</span><span
class="na">getAddress</span><span class="o">();</span>
+ <span class="kt">int</span> <span class="n">port</span> <span
class="o">=</span> <span class="n">cnf</span><span class="o">.</span><span
class="na">getPort</span><span class="o">();</span>
+ <span class="o">...</span>
+ <span class="o">}</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span
class="nc">Activator</span> <span class="kd">extends</span> <span
class="n">DependencyActivatorBase</span> <span class="o">{</span>
+ <span class="nd">@Override</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">init</span><span class="o">(</span><span
class="n">BundleContext</span> <span class="n">ctx</span><span
class="o">,</span> <span class="n">DependencyManager</span> <span
class="n">dm</span><span class="o">)</span> <span class="kd">throws</span>
<span class="n">Exception</span> <span class="o">{</span>
+ <span class="n">dm</span><span class="o">.</span><span
class="na">add</span><span class="o">(</span><span
class="n">createComponent</span><span class="o">()</span>
+ <span class="o">.</span><span
class="na">setImplementation</span><span class="o">(</span><span
class="n">ServiceImpl</span><span class="o">.</span><span
class="na">class</span><span class="o">)</span>
+ <span class="o">.</span><span class="na">add</span><span
class="o">(</span><span class="n">createConfigurationDependency</span><span
class="o">().</span><span class="na">setCallback</span><span
class="o">(</span><span class="s">"updated"</span><span
class="o">,</span> <span class="n">MyConfig</span><span class="o">.</span><span
class="na">class</span><span class="o">);</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
<h2 id="configurationdependency">@ConfigurationDependency<a class="headerlink"
href="#configurationdependency" title="Permanent link">¶</a></h2>
-<p>A configuration dependency is always required, and allows you to depend on
the availability of a valid configuration for your component. This dependency
requires the OSGi Configuration Admin Service.</p>
-<p>Annotation attributes:</p>
+<p>Configuration dependencies can be defined usnig the
@ConfigurationDependency.
+Annotation attributes:</p>
<ul>
<li><em>pid</em>: Returns the pid for a given service (by default, the pid is
the service class name).</li>
-<li><em>pidClass</em>: Will the the name of the specified class as the the pid
for a given service (by default, the pid is the service class name).</li>
<li><em>propagate</em>: Returns true if the configuration properties must be
published along with the service. Any additional service properties specified
directly are merged with these.</li>
-<li><em>name</em>: The name for this configuration dependency. When you give a
name a dependency, it won't be evaluated immediately, but after the component's
init method has been called,
-and from the init method, you can then return a map in order to dynamically
configure the
-configuration dependency (the map has to contain a "pid" and/or "propagate"
flag, prefixed
-with the dependency name). Then the dependency will be evaluated after the
component init
-method, and will be injected before the start method. </li>
</ul>
-<h2 id="usage-examples">Usage Examples<a class="headerlink"
href="#usage-examples" title="Permanent link">¶</a></h2>
-<p>In the following example, the "Printer" component depends on a
configuration whose PID name is "org.apache.felix.sample.Printer". This service
will initialize its ip/port number from the provided configuration:</p>
+<p>In the following example, the "Printer" component depends on a
configuration with "org.apache.felix.sample.Printer" PID.</p>
<div class="codehilite"><pre><span class="kn">package</span> <span
class="n">org</span><span class="o">.</span><span class="na">apache</span><span
class="o">.</span><span class="na">felix</span><span class="o">.</span><span
class="na">sample</span><span class="o">;</span>
<span class="nd">@Component</span>
@@ -120,7 +187,7 @@ method, and will be injected before the
WebConsole GUI. Using these meta data, you can specify for example the default
value for your
configurations data, some descriptions, the cardinality of configuration
values, etc ...
(we use here standard bnd metatype annotations, <a
href="http://www.aqute.biz/Bnd/MetaType">see bnd metatype documentation
here</a>.</p>
-<p>First, we define the configuration metadata, using standard bndtools
metatatype annotations:</p>
+<p>First, we define our PrinterConfiguration interface annotated with standard
bndtools metatatype annotations:</p>
<div class="codehilite"><pre> <span class="p">:::</span><span
class="n">java</span>
<span class="n">package</span> <span class="n">sample</span><span
class="p">;</span>
<span class="n">import</span> <span class="n">aQute</span><span
class="p">.</span><span class="n">bnd</span><span class="p">.</span><span
class="n">annotation</span><span class="p">.</span><span
class="n">metatype</span><span class="p">.</span><span
class="n">Meta</span><span class="p">.</span><span class="n">AD</span><span
class="p">;</span>
@@ -137,71 +204,28 @@ configurations data, some descriptions,
</pre></div>
-<p>Next, we define our Printer service which instantiates the
PrinterConfiguration using the *Configurable" bndlib helper:</p>
+<p>Next, we define our Printer service with an <code>updated</code> method
which is injected with the
+PrinterConfiguration type that is implemented by DM (all interface methods
will lookup in the
+actual configuration dictionary).</p>
<div class="codehilite"><pre> <span class="p">:::</span><span
class="n">java</span>
<span class="n">package</span> <span class="n">sample</span><span
class="p">;</span>
<span class="n">import</span> <span class="n">aQute</span><span
class="p">.</span><span class="n">bnd</span><span class="p">.</span><span
class="n">annotation</span><span class="p">.</span><span
class="n">metatype</span><span class="o">.*</span><span class="p">;</span>
<span class="p">@</span><span class="n">Component</span>
<span class="n">public</span> <span class="n">class</span> <span
class="n">Printer</span> <span class="p">{</span>
- <span class="p">@</span><span
class="n">ConfigurationDependency</span><span class="p">(</span><span
class="n">pidClass</span> <span class="p">=</span> <span
class="n">PrinterConfiguration</span><span class="p">.</span><span
class="n">class</span><span class="p">)</span> <span class="o">//</span> <span
class="n">Will</span> <span class="n">use</span> <span class="n">pid</span>
"<span class="n">sample</span><span class="p">.</span><span
class="n">PrinterConfiguration</span>"
- <span class="n">void</span> <span class="n">updated</span><span
class="p">(</span><span class="n">Dictionary</span> <span
class="n">props</span><span class="p">)</span> <span class="p">{</span>
- <span class="o">//</span> <span class="n">load</span> <span
class="n">configuration</span> <span class="n">from</span> <span
class="n">the</span> <span class="n">provided</span> <span
class="n">dictionary</span><span class="p">,</span> <span class="n">or</span>
<span class="n">throw</span> <span class="n">an</span> <span
class="n">exception</span> <span class="n">of</span> <span class="n">any</span>
<span class="n">configuration</span> <span class="n">error</span><span
class="p">.</span>
- <span class="n">PrinterConfig</span> <span class="n">cnf</span> <span
class="p">=</span> <span class="n">Configurable</span><span
class="p">.</span><span class="n">createConfigurable</span><span
class="p">(</span><span class="n">PrinterConfig</span><span
class="p">.</span><span class="n">class</span><span class="p">,</span> <span
class="n">props</span><span class="p">);</span>
- <span class="n">String</span> <span class="n">ip</span> <span
class="p">=</span> <span class="n">cnf</span><span class="p">.</span><span
class="n">ipAddress</span><span class="p">();</span>
- <span class="n">int</span> <span class="n">port</span> <span
class="p">=</span> <span class="n">cnf</span><span class="p">.</span><span
class="n">portNumber</span><span class="p">();</span>
- <span class="p">...</span>
+ <span class="p">@</span><span class="n">ConfigurationDependency</span>
<span class="o">//</span> <span class="n">Will</span> <span
class="n">use</span> <span class="n">pid</span> "<span
class="n">sample</span><span class="p">.</span><span
class="n">PrinterConfiguration</span>"
+ <span class="n">void</span> <span class="n">updated</span><span
class="p">(</span><span class="n">PrinterConfiguration</span> <span
class="n">cnf</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span
class="n">cnf</span> !<span class="p">=</span> <span class="n">null</span><span
class="p">)</span> <span class="p">{</span>
+ <span class="o">//</span> <span class="n">load</span> <span
class="n">configuration</span> <span class="n">from</span> <span
class="n">the</span> <span class="n">provided</span> <span
class="n">dictionary</span><span class="p">,</span> <span class="n">or</span>
<span class="n">throw</span> <span class="n">an</span> <span
class="n">exception</span> <span class="n">of</span> <span class="n">any</span>
<span class="n">configuration</span> <span class="n">error</span><span
class="p">.</span>
+ <span class="n">String</span> <span class="n">ip</span> <span
class="p">=</span> <span class="n">cnf</span><span class="p">.</span><span
class="n">ipAddress</span><span class="p">();</span>
+ <span class="n">int</span> <span class="n">port</span> <span
class="p">=</span> <span class="n">cnf</span><span class="p">.</span><span
class="n">portNumber</span><span class="p">();</span>
+ <span class="p">...</span>
+ <span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
-
-
-<p>Finally, the last example shows how to dynamically configure a
configuration dependency pid from the init method.
-The following component first depends on a "sample.MyComponent" configuration
pid. Then the init method gets from that configuration
-another pid for a second "global" configuration:</p>
-<div class="codehilite"><pre><span class="kn">package</span> <span
class="n">sample</span><span class="o">;</span>
-
-<span class="cm">/**</span>
-<span class="cm"> * A Service that dynamically defines an extra dynamic
configuration dependency from its init method. </span>
-<span class="cm"> */</span>
-<span class="nd">@Component</span>
-<span class="kd">class</span> <span class="nc">MyComponent</span> <span
class="o">{</span>
- <span class="kd">private</span> <span class="n">Dictionary</span> <span
class="n">m_config</span><span class="o">;</span>
-
- <span class="c1">// Inject initial Configuration (injected before any
other required dependencies)</span>
- <span class="nd">@ConfigurationDependency</span>
- <span class="kt">void</span> <span
class="nf">componentConfiguration</span><span class="o">(</span><span
class="n">Dictionary</span> <span class="n">config</span><span
class="o">)</span> <span class="o">{</span>
- <span class="c1">// you must throw an exception if the configuration
is not valid</span>
- <span class="n">m_config</span> <span class="o">=</span> <span
class="n">config</span><span class="o">;</span>
- <span class="o">}</span>
-
- <span class="cm">/**</span>
-<span class="cm"> * All unnamed dependencies are injected: we can now
configure our dynamic configuration whose dependency name is
"global".</span>
-<span class="cm"> */</span>
- <span class="nd">@Init</span>
- <span class="n">Map</span> <span class="nf">init</span><span
class="o">()</span> <span class="o">{</span>
- <span class="n">Map</span> <span class="n">properties</span> <span
class="o">=</span> <span class="k">new</span> <span
class="n">HashMap</span><span class="o">();</span>
- <span class="n">properties</span><span class="o">.</span><span
class="na">put</span><span class="o">(</span><span
class="s">"global.pid"</span><span class="o">,</span> <span
class="n">m_config</span><span class="o">.</span><span
class="na">get</span><span class="o">(</span><span
class="s">"globalConfig.pid"</span><span class="o">));</span>
- <span class="n">properties</span><span class="o">.</span><span
class="na">put</span><span class="o">(</span><span
class="s">"global.propagate"</span><span class="o">,</span> <span
class="n">m_config</span><span class="o">.</span><span
class="na">get</span><span class="o">(</span><span
class="s">"globalConfig.propagate"</span><span class="o">));</span>
- <span class="k">return</span> <span class="n">properties</span><span
class="o">;</span>
- <span class="o">}</span>
-
- <span class="c1">// Injected after init, and dynamically configured by the
init method.</span>
- <span class="nd">@ConfigurationDependency</span><span
class="o">(</span><span class="n">name</span><span class="o">=</span><span
class="s">"global"</span><span class="o">)</span>
- <span class="kt">void</span> <span
class="nf">globalConfiguration</span><span class="o">(</span><span
class="n">Dictionary</span> <span class="n">globalConfig</span><span
class="o">)</span> <span class="o">{</span>
- <span class="c1">// you must throw an exception if the configuration
is not valid</span>
- <span class="o">}</span>
-
- <span class="cm">/**</span>
-<span class="cm"> * All dependencies are injected and our service is now
ready to be published.</span>
-<span class="cm"> */</span>
- <span class="nd">@Start</span>
- <span class="kt">void</span> <span class="nf">start</span><span
class="o">()</span> <span class="o">{</span>
- <span class="o">}</span>
-<span class="o">}</span>
-</pre></div>
<div class="timestamp" style="margin-top: 30px; font-size: 80%;
text-align: right;">
- Rev. 1665812 by marrs on Wed, 11 Mar 2015 09:02:04 +0000
+ Rev. 1732044 by pderop on Wed, 24 Feb 2016 09:26:47 +0000
</div>
<div class="trademarkFooter">
Apache Felix, Felix, Apache, the Apache feather logo, and the Apache
Felix project