blob: 4b09084ff397edb807a1e5fbc83c4f539c3119f3 [file] [log] [blame]
Clement Escoffier50254022008-05-16 20:33:54 +00001<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Clement Escoffier3e0db1e2009-01-15 15:35:17 +00002<html><head>
3
4
Clement Escoffier50254022008-05-16 20:33:54 +00005
Clement Escoffier3e0db1e2009-01-15 15:35:17 +00006 <title>Apache Felix - Service Requirement Handler</title>
7 <link rel="stylesheet" href="service-requirement-handler_files/site.css" type="text/css" media="all">
8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
9 </head><body>
10 <div class="title"><div class="logo"><a href="http://felix.apache.org/site/index.html"><img alt="Apache Felix" src="service-requirement-handler_files/logo.png" border="0"></a></div><div class="header"><a href="http://www.apache.org/"><img alt="Apache" src="service-requirement-handler_files/apache.png" border="0"></a></div></div>
11 <div class="menu">
12<ul>
13 <li><a href="http://felix.apache.org/site/news.html" title="news">news</a></li>
14 <li><a href="http://felix.apache.org/site/license.html" title="license">license</a></li>
15 <li><span class="nobr"><a href="http://felix.apache.org/site/downloads.cgi" title="Visit page outside Confluence" rel="nofollow">downloads<sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span></li>
16 <li><a href="http://felix.apache.org/site/documentation.html" title="documentation">documentation</a></li>
17 <li><a href="http://felix.apache.org/site/mailinglists.html" title="mailinglists">mailing lists</a></li>
18 <li><a href="http://felix.apache.org/site/contributing.html" title="Contributing">contributing</a></li>
19 <li><span class="nobr"><a href="http://www.apache.org/" title="Visit page outside Confluence" rel="nofollow">asf<sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span></li>
20 <li><span class="nobr"><a href="http://www.apache.org/foundation/sponsorship.html" title="Visit page outside Confluence" rel="nofollow">sponsorship<sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span></li>
21 <li><span class="nobr"><a href="http://www.apache.org/foundation/thanks.html" title="Visit page outside Confluence" rel="nofollow">sponsors<sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span>
Clement Escoffier50254022008-05-16 20:33:54 +000022<!-- ApacheCon Ad -->
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000023<iframe src="service-requirement-handler_files/button.html" style="border-width: 0pt; float: left;" scrolling="no" width="135" frameborder="0" height="135"></iframe>
24<p style="height: 100px;">
25<!-- ApacheCon Ad -->
26</p></li></ul> </div>
27 <div class="main">
28<table class="sectionMacro" border="0" cellpadding="5" cellspacing="0" width="100%"><tbody><tr>
29<td class="confluenceTd" valign="top" width="80%">
30<h1><a name="ServiceRequirementHandler-ServiceDependencyManagement"></a>Service Dependency Management</h1>
Clement Escoffier50254022008-05-16 20:33:54 +000031
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000032<p>The dependency handler manages <em>OSGi service</em> <em>dependencies/requirements</em>.
33It allows a component to consume service without managing service
34discovery, tracking and binding. The handler manages all this
35interaction and injects required service in the component.</p>
Clement Escoffier50254022008-05-16 20:33:54 +000036
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000037<h2><a name="ServiceRequirementHandler-ServiceRequirement"></a>Service Requirement</h2>
Clement Escoffier50254022008-05-16 20:33:54 +000038
39
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000040<h3><a name="ServiceRequirementHandler-What'saservicerequirement?"></a>What's a service requirement?</h3>
Clement Escoffier50254022008-05-16 20:33:54 +000041
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000042<p>A requirement represents a required service. Therefore, it manages
43the service lookup and the service binding. When an instance requires a
44service, the handler injects directly a service object inside a field,
45or invokes a method when a consistent service appears (or disappears).
46Service requirements can be:</p>
47<ul>
48 <li>Simple / Aggregate : the component can require one or several service providers</li>
49 <li>Mandatory / Optional : a component can declare an optional dependency</li>
50 <li>Filtered : a component can filter available providers</li>
51 <li>Dynamic / Static / Dynamic-Priority : the component can specify the binding policy</li>
52 <li>Specific : the dependency targets a specific service provider</li>
53</ul>
Clement Escoffier50254022008-05-16 20:33:54 +000054
55
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000056<h3><a name="ServiceRequirementHandler-Dynamism&amp;InstanceLifecycle"></a>Dynamism &amp; Instance Lifecycle</h3>
Clement Escoffier50254022008-05-16 20:33:54 +000057
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000058<p>In OSGi™, services can appear and disappear dynamically. This
59implies dependencies can target a provider which can appear or
60disappear dynamically.&nbsp; So, dependencies need to manage this
61dynamism by tracking every time available services. At any moment, a
62dependency can be unresolved (i.e. no more provider can fulfill the
63requirement).&nbsp; In the case of a mandatory requirement, the
64instance becomes invalid (an invalid instance is no more accessible
65externally, for example provided service are unpublished). If a
66service, resolving the unfilled dependency appears, the instance
67becomes valid. In consequence, dependencies affect directly the
68instance state, and must manage correctly OSGi dynamism to allow a
69complete unloading when a service goes away. As soon a mandatory
70dependency cannot be fulfilled, the instance is invalidated.</p>
Clement Escoffier50254022008-05-16 20:33:54 +000071
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000072<p>By default, dependencies are managed dynamically (as previously
73explained). However, iPOJO supports two other types of binding
74policies:&nbsp;</p>
75<ul>
76 <li>Static : if a bound service disappears, the instance is invalidated and cannot be revalidated (binding broken)</li>
77 <li>Dynamic-Priority: at each injection, the <em>best</em> provider is injected, or the providers array is sorted according to the OSGi Ranking policy.</li>
78</ul>
Clement Escoffier50254022008-05-16 20:33:54 +000079
80
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000081<h2><a name="ServiceRequirementHandler-ServiceRequirementInjectionMechanisms"></a>Service Requirement Injection Mechanisms</h2>
Clement Escoffier50254022008-05-16 20:33:54 +000082
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000083<p>The handler manages two types of injections:</p>
84<ul>
85 <li>Field injection: a field contains the service object. As soon
86as the field is used, a consistent service object is injected. This
87injection type fully hides the dynamism</li>
88 <li>Method invocation:
89when a service appears, or disappears a method in the component is
90invoked. For each dependency, bind and unbind methods are invoke to
91notify the component of the event.</li>
92</ul>
Clement Escoffier50254022008-05-16 20:33:54 +000093
94
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000095<p>Moreover, the two injections type can be merged. A component can declare a requirement containing both a field and 'binding'.</p>
Clement Escoffier50254022008-05-16 20:33:54 +000096
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000097<h3><a name="ServiceRequirementHandler-Fieldinjection"></a>Field injection</h3>
Clement Escoffier50254022008-05-16 20:33:54 +000098
Clement Escoffier3e0db1e2009-01-15 15:35:17 +000099<p>Imagine a Hello service with one method 'getMessage' returning a
100"Hello Message". The following component implementation can use this
101service by attaching this service to a field and by using the field:</p>
102<div class="code"><div class="codeContent">
103<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
104 <span class="code-keyword">private</span> Hello m_hello;
105 <span class="code-keyword">public</span> doSomething() {
106 <span class="code-object">System</span>.out.println(m_hello.getMesage());
Clement Escoffier50254022008-05-16 20:33:54 +0000107 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000108}</pre>
109</div></div>
110<p>For this component, metadata could be:</p>
111<div class="code"><div class="codeContent">
112<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
113 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hello"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000114 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000115<span class="code-tag">&lt;/component&gt;</span></pre>
116</div></div>
117<p>The metadata contains a 'requires' element (representing the service
118dependency). This element has a field attribute. This attribute is the
119name of the field representing the service dependency in the
120implementation class. The implementation uses the field as a normal
121field without managing service interactions.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000122
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000123<h3><a name="ServiceRequirementHandler-Methodinvocation"></a>Method invocation</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000124
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000125<p>The second injection mechanism uses methods in the implementation
126class. By this way, the dynamics can be managed directly by the
127developer. Each dependency can declare two methods:</p>
128<ul>
129 <li>A bind method called when a service appears</li>
130 <li>An unbind method called when a service disappears</li>
131</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000132
133
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000134<p>Moreover, callbacks can be in the component super class (in this
135case methods must be public). These methods can have one of these four
136signatures:</p>
137<ul>
138 <li>Without any argument: the method is just a notification (method())</li>
139 <li>With the service object : the object is the implicated service object (method(Service svc))</li>
140 <li>With an OSGi service reference: the service reference appearing or disappearing (method(ServiceReference ref))</li>
141 <li>With the service object and the OSGi service reference (method(Service svc, ServiceReference ref))</li>
142 <li>With the service object and the service properties inside a Map (method(Service svc, Map properties)) <b>[New in the 1.1.0-SNAPSHOT version]</b></li>
143 <li>With the service object and the service properties inside a Dictionary (method(Service svc, Dictionary properties)) <b>[New in the 1.1.0-SNAPSHOT version]</b></li>
144</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000145
146
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000147<p>The following component implementation shows an example of implementation using this mechanism:</p>
148<div class="code"><div class="codeContent">
149<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
150 <span class="code-keyword">private</span> Hello m_hello;
Clement Escoffier50254022008-05-16 20:33:54 +0000151
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000152 <span class="code-keyword">public</span> void bindHello(Hello h) { m_hello = h; }
153 <span class="code-keyword">public</span> void unbindHello() { m_hello = <span class="code-keyword">null</span>; }
154 <span class="code-keyword">public</span> doSomething() { <span class="code-object">System</span>.out.println(m_hello.getMesage()); }
155}</pre>
156</div></div>
157<p>For this component, metadata could be:</p>
158<div class="code"><div class="codeContent">
159<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
160<span class="code-tag">&lt;requires&gt;</span>
161 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
162 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
163<span class="code-tag">&lt;/requires&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000164...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000165<span class="code-tag">&lt;/component&gt;</span></pre>
166</div></div>
167<p>Note, that the bind the unbind method can be have different
168signatures. By using this mechanism, you need to be sure to manage the
169dynamism correctly.<br>
170(<a href="#ServiceRequirementHandler-discovery" title="discovery on Service Requirement Handler">See note on type discovery</a>)</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000171
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000172<h3><a name="ServiceRequirementHandler-FieldinjectionsandMethodinvocations"></a>Field injections and Method invocations</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000173
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000174<p>The two mechanisms can be used together. In this case, the field
175receives the value before the bind method invocation. So, if the field
176is use in the method, the returned value will be up to date. The
177following component implementation uses this mechanism:</p>
178<div class="code"><div class="codeContent">
179<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
180 <span class="code-keyword">private</span> Hello m_hello; <span class="code-comment">// Injected Field
181</span>
182 <span class="code-keyword">public</span> void bindHello() { <span class="code-object">System</span>.out.println(<span class="code-quote">"Hello appears"</span>); }
183 <span class="code-keyword">public</span> void unbindHello() { <span class="code-object">System</span>.out.println(<span class="code-quote">"Hello disapears"</span>); }
184 <span class="code-keyword">public</span> doSomething() { <span class="code-object">System</span>.out.println(m_hello.getMesage()); }
185}</pre>
186</div></div>
Clement Escoffier130ca572008-10-13 07:33:03 +0000187
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000188<p>For this component, metadata could be:</p>
189<div class="code"><div class="codeContent">
190<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
191 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hello"</span>&gt;</span>
192 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
193 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
194 <span class="code-tag">&lt;/requires&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000195 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000196<span class="code-tag">&lt;/component&gt;</span></pre>
197</div></div>
Clement Escoffier50254022008-05-16 20:33:54 +0000198
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000199<h3><a name="ServiceRequirementHandler-Injectionmechanisms&amp;lazyobjectcreation"></a>Injection mechanisms &amp; lazy object creation</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000200
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000201<p>IPOJO creates objects only when required. When needed, iPOJO invokes
202the constructor of the implementation class. The implementation class
203can use field requirement because values are already injected. However,
204method dependencies are called just after the constructor. If the
205service already presents, the invocation of the methods are delayed
206just after the constructor invocation.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000207
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000208<h2><a name="ServiceRequirementHandler-SomeExamples"></a>Some Examples</h2>
Clement Escoffier50254022008-05-16 20:33:54 +0000209
210
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000211<h3><a name="ServiceRequirementHandler-SimpleRequirement"></a>Simple Requirement</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000212
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000213<p>By default, a requirement is mandatory, non-filtered and simple
214(non-aggregate). The two previous examples illustrate this kind of
215dependency. When services goes away and appears, the service
216substitution is hidden. Fields attached to simple requirement point
217always a consistent service object. For a simple dependency, the bind
218method is called once time when the service appears or just after the
219POJO constructor invocation is the service is available. When the
220service disappears the unbind method is called. The bind method is
221re-invoked as soon as another service provider is available. This
222invocation occurs immediately if another service provider if available.
223In this case, the instance is not invalidated.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000224
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000225<h3><a name="ServiceRequirementHandler-AggregateRequirement"></a>Aggregate Requirement</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000226
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000227<p>When a component requires several providers of the same service, it declares an aggregate dependency.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000228
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000229<h4><a name="ServiceRequirementHandler-AggregateDependencywithfieldinjection"></a>Aggregate Dependency with field injection</h4>
Clement Escoffier50254022008-05-16 20:33:54 +0000230
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000231<div class="code"><div class="codeContent">
232<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
233 <span class="code-keyword">private</span> Hello m_hellos[];
234 <span class="code-keyword">public</span> doSomething() {
235 <span class="code-keyword">for</span>(<span class="code-object">int</span> I = 0; I &lt; m_hellos.length; i++) {
236 <span class="code-object">System</span>.out.println(m_hellos[i].getMessage());
Clement Escoffier130ca572008-10-13 07:33:03 +0000237 }
Clement Escoffier50254022008-05-16 20:33:54 +0000238 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000239}</pre>
240</div></div>
Clement Escoffier130ca572008-10-13 07:33:03 +0000241
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000242<p>For this component, metadata could be:</p>
243<div class="code"><div class="codeContent">
244<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
245 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hellos"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000246 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000247<span class="code-tag">&lt;/component&gt;</span></pre>
248</div></div>
Clement Escoffier130ca572008-10-13 07:33:03 +0000249
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000250<p>To declare an aggregate field for field requirement, you only need
251to declare an array (instead of a scalar type). IPOJO will create and
252inject the service object array. iPOJO discover that the dependency is
253aggregate during the bytecode introspection.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000254
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000255<p><em>Note:</em> The synchronization is managed by iPOJO. As soon as
256you are 'touching' a dependency in a method, iPOJO ensure that you will
257keep these objects until the end of the method. Nested methods will
258share the same service object set.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000259
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000260<h4><a name="ServiceRequirementHandler-AggregateDependencywithfieldinjection:list,vector,collectionandset"></a>Aggregate Dependency with field injection: list, vector, collection and set</h4>
261<p>It is also possible to inject service objects inside fields of the type:</p>
262<ul>
263 <li>list</li>
264 <li>vector</li>
265 <li>collection</li>
266 <li>set</li>
267</ul>
Clement Escoffier130ca572008-10-13 07:33:03 +0000268
269
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000270<div class="code"><div class="codeContent">
271<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
272 <span class="code-keyword">private</span> List m_hellos;
273 <span class="code-keyword">public</span> doSomething() {
274 <span class="code-keyword">for</span>(<span class="code-object">int</span> I = 0; I &lt; m_hellos.size(); i++) {
275 <span class="code-object">System</span>.out.println(((Hello) m_hellos.get(i)).
Clement Escoffier130ca572008-10-13 07:33:03 +0000276 getMessage());
277 }
278 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000279}</pre>
280</div></div>
281<p>For this component, metadata could be:</p>
282<div class="code"><div class="codeContent">
283<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
284 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hellos"</span> specification=<span class="code-quote">"o.a.f.i.Hello"</span>/&gt;</span>
Clement Escoffier130ca572008-10-13 07:33:03 +0000285 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000286<span class="code-tag">&lt;/component&gt;</span></pre>
287</div></div>
288<p>In this case, just use the supported type that you want. iPOJO will
289automatically understand that it is an aggregate dependency, and will
290create the collection object containing service objects.<br>
291<em>Note:</em> The service specification (i.e. interface) cannot be
292discovered when using these types as the bytecode does not provide
293enough information. So, you have to indicate the required service
294interface (with the 'specification' attribute) in the requirement
295description.<br>
296<em>Note:</em> As in the previous case, the synchronization is managed
297by iPOJO. As soon as you are 'touching' a dependency in a method, iPOJO
298ensure that you will keep these objects until the end of the method.
299Nested methods will share the same service object set.</p>
Clement Escoffier130ca572008-10-13 07:33:03 +0000300
301
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000302<h4><a name="ServiceRequirementHandler-AggregateDependencywithmethodinvocation"></a>Aggregate Dependency with method invocation</h4>
Clement Escoffier50254022008-05-16 20:33:54 +0000303
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000304<div class="code"><div class="codeContent">
305<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
306 <span class="code-keyword">private</span> List m_hellos= <span class="code-keyword">new</span> ArrayList();
307 <span class="code-keyword">private</span> void bindHello(Hello h) { m_hellos.add(h); }
308 <span class="code-keyword">private</span> void unbindHello(Hello h) { m_hellos.remove(h); }
309 <span class="code-keyword">public</span> <span class="code-keyword">synchronized</span> doSomething() {
310 <span class="code-keyword">for</span>(<span class="code-object">int</span> I = 0; I &lt; m_hellos.size(); i++) {
311 <span class="code-object">System</span>.out.println(m_hellos.get(i).
Clement Escoffier130ca572008-10-13 07:33:03 +0000312 getMessage());
313 }
Clement Escoffier50254022008-05-16 20:33:54 +0000314 }
315 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000316}</pre>
317</div></div>
318<p>This requirement is configured as following:</p>
319<div class="code"><div class="codeContent">
320<pre class="code-xml"><span class="code-tag">&lt;requires aggregate=<span class="code-quote">"true"</span>&gt;</span>
321 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
322 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
323<span class="code-tag">&lt;/requires&gt;</span></pre>
324</div></div>
325<p>In this case, iPOJO cannot detect if the dependency is aggregate or not. So, you need to add the '<em>aggregate</em>' attribute. The bindHello and unbindHello will be called each time a Hello service appears or disappears.<br>
326<em>Note:</em> To avoid the list modification during the loop, you need
327synchronized the block. Indeed, as the field is not an iPOJO
328requirement, iPOJO will not manage the synchronization.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000329
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000330<h3><a name="ServiceRequirementHandler-OptionalRequirement(nonaggregate)"></a>Optional Requirement (non-aggregate)</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000331
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000332<p>An optional requirement does not invalidate the instance despite no
333providers are available. Moreover, it is possible to inject a default
334service implementation when no <em>real</em> providers are available.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000335
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000336<h4><a name="ServiceRequirementHandler-OptionalRequirementwithfieldinjection"></a>Optional Requirement with field injection</h4>
Clement Escoffier50254022008-05-16 20:33:54 +0000337
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000338<div class="code"><div class="codeContent">
339<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
340 <span class="code-keyword">private</span> Hello m_hello;
341 <span class="code-keyword">public</span> doSomething() {
342 <span class="code-object">System</span>.out.println(m_hello.getMesage());
Clement Escoffier130ca572008-10-13 07:33:03 +0000343 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000344}</pre>
345</div></div>
346<p>For this component, metadata could be:</p>
347<div class="code"><div class="codeContent">
348<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
349 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hello"</span> optional=<span class="code-quote">"true"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000350 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000351<span class="code-tag">&lt;/component&gt;</span></pre>
352</div></div>
353<p>To declare an optional requirement, you need to add the <em>'optional'</em> attribute. To avoid null pointer exception, iPOJO injects a <em>Nullable</em> object in the field when no service provider is available. The <em>nullable</em>
354object implements the service interface, but does nothing. Moreover, it
355is possible to set a default-implementation for the service. A
356default-implementation is a class implementing the service but used
357only when no others service providers are available. The
358default-implementation object will be injected instead of the <em>Nullable</em> objet. For further information <a href="#ServiceRequirementHandler-nullable" title="nullable on Service Requirement Handler">refer to the note about nullable object</a>.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000359
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000360<h4><a name="ServiceRequirementHandler-OptionalDependencywithmethodinvocation"></a>Optional Dependency with method invocation</h4>
Clement Escoffier50254022008-05-16 20:33:54 +0000361
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000362<div class="code"><div class="codeContent">
363<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
364 <span class="code-keyword">private</span> Hello m_hello;
365 <span class="code-keyword">public</span> void bindHello(Hello h) { m_hello = h; }
366 <span class="code-keyword">public</span> void unbindHello() { m_hello = <span class="code-keyword">null</span>; }
367 <span class="code-keyword">public</span> doSomething() {
368 <span class="code-keyword">if</span>(m_hello != <span class="code-keyword">null</span>) {
369 <span class="code-object">System</span>.out.println(m_hello.getMesage());
Clement Escoffier130ca572008-10-13 07:33:03 +0000370 }
371 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000372}</pre>
373</div></div>
374<p>For this component, metadata should be:</p>
375<div class="code"><div class="codeContent">
376<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
377<span class="code-tag">&lt;requires optional=<span class="code-quote">"true"</span>&gt;</span>
378 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
379 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
380<span class="code-tag">&lt;/requires&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000381...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000382<span class="code-tag">&lt;/component&gt;</span></pre>
383</div></div>
384<p>As for field requirement, the dependency metadata needs to contain
385the optional attribute. IPOJO invokes the method only when a 'real'
386service is available, so you need to test if m_hello is null before to
387use it.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000388
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000389<h3><a name="ServiceRequirementHandler-Aggregate&amp;OptionalRequirement"></a>Aggregate &amp; Optional Requirement</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000390
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000391<p>A dependency can be both aggregate and optional.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000392
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000393<h4><a name="ServiceRequirementHandler-Aggregate&amp;OptionalDependencywithfieldinjection"></a>Aggregate &amp; Optional Dependency with field injection</h4>
Clement Escoffier50254022008-05-16 20:33:54 +0000394
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000395<div class="code"><div class="codeContent">
396<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
397 <span class="code-keyword">private</span> Hello m_hellos[];
398 <span class="code-keyword">public</span> doSomething() {
399 <span class="code-keyword">for</span>(<span class="code-object">int</span> I = 0; I &lt; m_hellos.length; i++) {
400 <span class="code-object">System</span>.out.println(m_hellos[i].getMessage());
Clement Escoffier130ca572008-10-13 07:33:03 +0000401 }
Clement Escoffier50254022008-05-16 20:33:54 +0000402 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000403}</pre>
404</div></div>
405<p>For this component, metadata could be:</p>
406<div class="code"><div class="codeContent">
407<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
408<span class="code-tag">&lt;requires field=<span class="code-quote">"m_hellos"</span> optional=<span class="code-quote">"true"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000409...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000410<span class="code-tag">&lt;/component&gt;</span></pre>
411</div></div>
412<p>To declare an optional &amp; aggregate field requirement you need to
413write the optional attribute in the dependency metadata and to point on
414a field array. If no service available, iPOJO injects an empty array.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000415
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000416<h4><a name="ServiceRequirementHandler-Aggregate&amp;OptionalRequirementwithmethodinvocation"></a>Aggregate &amp; Optional Requirement with method invocation</h4>
Clement Escoffier50254022008-05-16 20:33:54 +0000417
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000418<div class="code"><div class="codeContent">
419<pre class="code-java"><span class="code-keyword">public</span> class HelloConsumer {
420 <span class="code-keyword">private</span> List m_hellos&lt;Hello&gt; = <span class="code-keyword">new</span> ArrayList&lt;Hello&gt;();
421 <span class="code-keyword">private</span> void bindHello(Hello h) { m_hellos.add(h); }
422 <span class="code-keyword">private</span> void unbindHello(Hello h) { m_hellos.remove(h); }
423 <span class="code-keyword">public</span> <span class="code-keyword">synchronized</span> doSomething() {
424 <span class="code-keyword">for</span>(<span class="code-object">int</span> I = 0; I &lt; m_hellos.size(); i++) {
425 <span class="code-object">System</span>.out.println(m_hellos.get(i).getMessage());
Clement Escoffier130ca572008-10-13 07:33:03 +0000426 }
Clement Escoffier50254022008-05-16 20:33:54 +0000427 }
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000428}</pre>
429</div></div>
430<p>For this component, metadata could be:</p>
431<div class="code"><div class="codeContent">
432<pre class="code-xml"><span class="code-tag">&lt;requires aggregate=<span class="code-quote">"true"</span> optional=<span class="code-quote">"true"</span>&gt;</span>
433 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
434 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
435<span class="code-tag">&lt;/requires&gt;</span></pre>
436</div></div>
437<p>In this case, you need to add the _'aggregate'_attribute and the
438_'optional'_attribute. The bindHello and unbindHello will be called
439each time a Hello service appears or disappears. These bind / unbind
440methods are not called when binding / unbinding a Nullable object (when
441both field and method are used).</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000442
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000443<h3><a name="ServiceRequirementHandler-FilteredRequirement"></a>Filtered Requirement</h3>
Clement Escoffier50254022008-05-16 20:33:54 +0000444
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000445<p>A filtered dependency applies an LDAP filter on service provider.
446IPOJO reuses OSGi LDAP filter ability. The following metadata
447illustrates how to use filters:</p>
448<div class="code"><div class="codeContent">
449<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
450<span class="code-tag">&lt;requires filter=<span class="code-quote">"(language=fr)"</span>&gt;</span>
451 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
452 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
453<span class="code-tag">&lt;/requires&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000454...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000455<span class="code-tag">&lt;/component&gt;</span></pre>
456</div></div>
457<p>To add a filter, just add a 'filter' attribute in your dependency
458containing the LDAP filter. iPOJO will select only provider matching
459with this filter.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000460
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000461<p>Moreover, filters can be customized instance by instance. It is
462possible to specialize / change / add the filter of a component in the
463instance description. It is useful when you want to create different
464instances of the same component, with different filter. To do it, you
465have to identify your dependency with an 'id' attribute. Then, you can
466adapt the filter of the dependency in the instance description by using
467the property "requires.filters". In this property you can specify each
468dependency identified by its id and the new value of the filter.</p>
469<div class="code"><div class="codeContent">
470<pre class="code-xml">&lt;component
471 className=<span class="code-quote">"org.apache.felix.ipojo.example.FilteredDependency"</span>
472 name=<span class="code-quote">"FOO"</span>&gt;
473 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_foo"</span> fiter=<span class="code-quote">"(foo.property=FOO)"</span> id=<span class="code-quote">"id1"</span>&gt;</span>
474 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bind"</span>/&gt;</span>
475 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbind"</span>/&gt;</span>
476 <span class="code-tag">&lt;/requires&gt;</span>
477<span class="code-tag">&lt;/component&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000478
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000479<span class="code-tag">&lt;instance name=<span class="code-quote">"FOO1"</span> component=<span class="code-quote">"FOO"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000480
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000481<span class="code-tag">&lt;instance name=<span class="code-quote">"FOO2"</span> component=<span class="code-quote">"FOO"</span>&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000482
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000483 <span class="code-tag">&lt;property name=<span class="code-quote">"requires.filters"</span>&gt;</span>
484 <span class="code-tag">&lt;property name=<span class="code-quote">"id1"</span> value=<span class="code-quote">"(foo.property=BAR)"</span>/&gt;</span>
485 <span class="code-tag">&lt;/property&gt;</span>
486<span class="code-tag">&lt;/instance&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000487
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000488<span class="code-tag">&lt;instance name=<span class="code-quote">"FOO3"</span> component=<span class="code-quote">"FOO"</span>&gt;</span>
489 <span class="code-tag">&lt;property name=<span class="code-quote">"requires.filters"</span>&gt;</span>
490 <span class="code-tag">&lt;property name=<span class="code-quote">"id1"</span> value=<span class="code-quote">"(foo.property=BAZ)"</span>/&gt;</span>
491 <span class="code-tag">&lt;/property&gt;</span>
492<span class="code-tag">&lt;/instance&gt;</span></pre>
493</div></div>
494<p>The FOO component type declares a service dependency with the 'id1'
495id. This dependency has no filter by default. The first instance is
496just an instance of the FOO component type and does not modify the
497dependency. The second one adds a filter to the declared dependency to
498target providers with foo.property = BAR. The last one adds another
499filter to the declared dependency. By using instance filter
500customization, it is possible to create complex applications where you
501avoid binding problems by filtering dependencies instance by instance.</p>
502
503<h3><a name="ServiceRequirementHandler-Targetingaspecificprovider"></a>Targeting a specific provider</h3>
504<p>A service dependency can choose a specific provider. To achieve
505this, add a 'from' attribute in your requirement description such as in:</p>
506<div class="code"><div class="codeContent">
507<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
508<span class="code-tag">&lt;requires from=<span class="code-quote">"MyHelloProvider"</span>&gt;</span>
509 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bindHello"</span>&gt;</span>
510 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbindHello"</span>&gt;</span>
511<span class="code-tag">&lt;/requires&gt;</span>
Clement Escoffier130ca572008-10-13 07:33:03 +0000512...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000513<span class="code-tag">&lt;/component&gt;</span></pre>
514</div></div>
515<p>iPOJO maps the from attribute to a specific filter :
516'|(instance.name=MyHelloProvider)(service.pid=MyHelloProvider)'. Then
517the dependency can only be fulfilled by a service matching this filter.</p>
Clement Escoffier130ca572008-10-13 07:33:03 +0000518
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000519<p>Moreover, from attributes can be customized instance by instance. It
520is possible to specialize / change / add a 'from' attribute of a
521component in the instance configuration. It is useful when you want to
522create different instances of the same component, with different 'from'
523clauses. To do it, you have to identify your dependency with an 'id'
524attribute. Then, you can adapt the 'from' of the dependency in the
525instance configuration by using the property "requires.from". In this
526property you can specify each dependency identified by its id and the
527'from' value.</p>
Clement Escoffier130ca572008-10-13 07:33:03 +0000528
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000529<div class="code"><div class="codeContent">
530<pre class="code-xml">&lt;component
531 className=<span class="code-quote">"org.apache.felix.ipojo.example.FilteredDependency"</span>
532 name=<span class="code-quote">"FOO"</span>&gt;
533 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_foo"</span> id=<span class="code-quote">"id1"</span>&gt;</span>
534 <span class="code-tag">&lt;callback type=<span class="code-quote">"bind"</span> method=<span class="code-quote">"bind"</span>/&gt;</span>
535 <span class="code-tag">&lt;callback type=<span class="code-quote">"unbind"</span> method=<span class="code-quote">"unbind"</span>/&gt;</span>
536 <span class="code-tag">&lt;/requires&gt;</span>
537<span class="code-tag">&lt;/component&gt;</span>
Clement Escoffier130ca572008-10-13 07:33:03 +0000538
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000539<span class="code-tag">&lt;instance name=<span class="code-quote">"FOO1"</span> component=<span class="code-quote">"FOO"</span>/&gt;</span>
Clement Escoffier130ca572008-10-13 07:33:03 +0000540
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000541<span class="code-tag">&lt;instance name=<span class="code-quote">"FOO2"</span> component=<span class="code-quote">"FOO"</span>&gt;</span>
542 <span class="code-tag">&lt;property name=<span class="code-quote">"requires.from"</span>&gt;</span>
543 <span class="code-tag">&lt;property name=<span class="code-quote">"id1"</span> value=<span class="code-quote">"myprovider"</span>/&gt;</span>
544 <span class="code-tag">&lt;/property&gt;</span>
545<span class="code-tag">&lt;/instance&gt;</span>
Clement Escoffier130ca572008-10-13 07:33:03 +0000546
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000547<span class="code-tag">&lt;instance name=<span class="code-quote">"FOO3"</span> component=<span class="code-quote">"FOO"</span>&gt;</span>
548 <span class="code-tag">&lt;property name=<span class="code-quote">"requires.from"</span>&gt;</span>
549 <span class="code-tag">&lt;property name=<span class="code-quote">"id1"</span> value=<span class="code-quote">"myotherprovider"</span>/&gt;</span>
550 <span class="code-tag">&lt;/property&gt;</span>
551<span class="code-tag">&lt;/instance&gt;</span></pre>
552</div></div>
Clement Escoffier130ca572008-10-13 07:33:03 +0000553
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000554<p>The FOO component type declares a service dependency with the 'id1'
555id. This dependency has no 'from' attribute by default. The first
556instance is just an instance of the FOO component type and does not
557modify the dependency. The second one adds a 'from' attribute to the
558declared dependency to target the 'myprovider' provider. The last one
559adds another 'from' clause to the declared dependency.</p>
Clement Escoffier130ca572008-10-13 07:33:03 +0000560
561
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000562<h2><a name="ServiceRequirementHandler-BindingPolicies"></a>Binding Policies</h2>
Clement Escoffier50254022008-05-16 20:33:54 +0000563
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000564<p>Three binding policies are supported inside iPOJO.</p>
565<ul>
566 <li>Dynamic policy (default): the binding are managed
567dynamically. At each injection, the same provider is injected if the
568provider is always available. Else a new one is chosen. For aggregate
569dependency, the array order does not change; new providers are placed
570at the end of the array.</li>
571 <li>Static policy: the binding is
572static. So, once bound a provider cannot disappear. If it disappears,
573the instance is invalidated and cannot be revalidated without stopping
574and restarting the instance.</li>
575 <li>Dynamic-priority policy: the
576binding is managed dynamically but the injected provider is selected by
577using a ranking policy. Two injections can return two different
578providers, is a new provider is 'better' than the previous one, despite
579the first one is always available. For aggregate dependency, the array
580is sorted.</li>
581</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000582
583
Clement Escoffier130ca572008-10-13 07:33:03 +0000584
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000585<p>A static binding is declared as following:</p>
586
587<div class="code"><div class="codeContent">
588<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
589 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hellos"</span> policy=<span class="code-quote">"static"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000590 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000591<span class="code-tag">&lt;/component&gt;</span></pre>
592</div></div>
Clement Escoffier130ca572008-10-13 07:33:03 +0000593
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000594<p>A dynamic-priority binding is declared as following:</p>
595<div class="code"><div class="codeContent">
596<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
597 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hellos"</span> policy=<span class="code-quote">"dynamic-priority"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000598 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000599<span class="code-tag">&lt;/component&gt;</span></pre>
600</div></div>
601<p>By default, the dynamic-priority policy uses the OSGi service
602ranking policy. However, it is possible to customize the policy by
603adding the '<em>comparator</em>' attribute. This attribute indicates
604the class name of a class implementing the java.util.Comparator
605interface. IPOJO will create an instance of your comparator and use it
606to sort service references (so your customized comparator needs to be
607able to sort OSGi Service Reference).</p>
608<div class="code"><div class="codeContent">
609<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...HelloConsumer"</span>&gt;</span>
610 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_hellos"</span> policy=<span class="code-quote">"dynamic-priority"</span> comparator=<span class="code-quote">"my.great.Comparator"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000611 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000612<span class="code-tag">&lt;/component&gt;</span></pre>
613</div></div>
Clement Escoffier50254022008-05-16 20:33:54 +0000614
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000615<p><a name="ServiceRequirementHandler-nullable"></a></p>
616<h2><a name="ServiceRequirementHandler-Noteaboutnullableobject&amp;defaultimplementation"></a>Note about nullable object &amp; default-implementation</h2>
Clement Escoffier50254022008-05-16 20:33:54 +0000617
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000618<p>The instance implementation can use an optional dependency without
619any checking. Indeed, when an instance declares an optional dependency
620using field injection, iPOJO create on the fly a Nullable class
621implementing the service specification but doing nothing (mock object).
622Therefore, iPOJO cannot return a service to the instance, for an
623optional dependency, it returns a nullable object.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000624
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000625<p>A nullable object returns:</p>
626<ul>
627 <li>Null when the method returns an object</li>
628 <li>0 when the method returns an int, log, byte, short, char, float or a double</li>
629 <li>False when the method return a boolean</li>
630</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000631
632
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000633<p>You can check if the returned object is a nullable object with the test: <em>"myservice instanceof Nullable"</em>.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000634
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000635<p>You can disable the Nullable pattern too (activated by default). In this case, iPOJO will inject <em>null</em> instead of a <em>Nullable</em> object. So, you can just test if your field is equals to <em>null</em>
636to check if the service is available. To disable the Nullable pattern,
637you need to add the 'nullable="false"' attribute in your service
638dependency description as follows:</p>
639<div class="code"><div class="codeContent">
640<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...LogExample"</span>&gt;</span>
641 <span class="code-tag">&lt;requires field=<span class="code-quote">"m_log"</span> optional=<span class="code-quote">"true"</span> nullable=<span class="code-quote">"false"</span>/&gt;</span>
Clement Escoffier50254022008-05-16 20:33:54 +0000642 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000643<span class="code-tag">&lt;/component&gt;</span></pre>
644</div></div>
Clement Escoffier50254022008-05-16 20:33:54 +0000645
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000646<p>However, you can also indicate a <em>default-implementation</em> for
647your optional service. In this case, if no providers are found, iPOJO
648creates an instance of the default-implementation and injects it. The
649default-implementation attribute describes the class name of your
650implementation. The given class <b>MUST</b> implement the required service interface.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000651
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000652<p>For example, the following component uses a default implementation for a Log Service dependency:</p>
653<div class="code"><div class="codeContent">
654<pre class="code-xml"><span class="code-tag">&lt;component classname=<span class="code-quote">"...LogExample"</span>&gt;</span>
655 &lt;requires field=<span class="code-quote">"m_log"</span> optional=<span class="code-quote">"true"</span>
Clement Escoffier130ca572008-10-13 07:33:03 +0000656 default-implementation=
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000657 <span class="code-quote">"org.apache.felix.ipojo.example.default.MyLogService"</span>/&gt;
Clement Escoffier50254022008-05-16 20:33:54 +0000658 ...
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000659<span class="code-tag">&lt;/component&gt;</span></pre>
660</div></div>
661<p>If the log service is not available, iPOJO creates an object of the
662'org.apache.felix.ipojo.example.default.MyLogService' class. This
663object is injected instead of a Nullable object. For instance, the
664default implementation can print messages on the System.err stream. The
665nullable object does no display anything.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000666
667
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000668<p><a name="ServiceRequirementHandler-callbacks"></a></p>
669<h2><a name="ServiceRequirementHandler-NoteaboutCallbacks"></a>Note about Callbacks</h2>
670<p>Dependency manages two type of callback: bind and unbind. A callback
671with a type "bind" is called each type that a service provider arrives
672and the binding is necessary. According to the cardinality of the
673dependency it means:</p>
674<ul>
675 <li>Simple dependency : at the firs binding and at each rebinding to another service provider</li>
676 <li>Aggregate dependencies: each time that a service provider arrives</li>
677</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000678
679
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000680<p>An unbind callback is called each time that a <b>used</b> service
681provider goes away. For a simple dependency this method is called each
682time that the used service provider goes away. For a multiple
683dependency this method is called each time that a service provider goes
684away.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000685
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000686<p>The method can receive in argument the service object or the service
687reference (in order to obtain service properties). The bind methods are
688delayed since a POJO object is created.</p>
Clement Escoffier50254022008-05-16 20:33:54 +0000689
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000690<p><a name="ServiceRequirementHandler-discovery"></a></p>
691<h2><a name="ServiceRequirementHandler-Noteonserviceinterfacediscovery"></a>Note on service interface discovery</h2>
Clement Escoffier50254022008-05-16 20:33:54 +0000692
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000693<p>The <tt>specification</tt> attribute is generally optional except
694when iPOJO cannot discover the type of the service. iPOJO cannot infer
695the type when the dependency has no field and callbacks do not receive
696the service object in parameter. In this case, you need to declare the
697service interface.</p>
698</td>
699<td class="confluenceTd" valign="top" width="20%">
700<h6><a name="ServiceRequirementHandler-Overview"></a><b>Overview</b></h6>
701<ul>
702 <li><a href="http://felix.apache.org/site/apache-felix-ipojo.html" title="Apache Felix iPOJO">Home Page</a></li>
703 <li><a href="http://felix.apache.org/site/apache-felix-ipojo-feature-overview.html" title="Apache Felix iPOJO Feature Overview">iPOJO Feature Overview</a></li>
704 <li><a href="http://felix.apache.org/site/download.html" title="Download">Download &amp; Install </a></li>
705</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000706
707
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000708<h6><a name="ServiceRequirementHandler-GettingStarted"></a><b>Getting Started</b></h6>
709<ul>
710 <li><a href="http://felix.apache.org/site/ipojo-in-10-minutes.html" title="iPOJO in 10 minutes">iPOJO in 10 minutes</a></li>
711 <li><a href="http://felix.apache.org/site/how-to-use-ipojo-annotations.html" title="How to use iPOJO Annotations">How to use iPOJO Annotations</a></li>
712 <li><a href="http://felix.apache.org/site/ipojo-hello-word-maven-based-tutorial.html" title="iPOJO Hello Word (Maven-Based) tutorial">iPOJO Hello Word (Maven-Based) tutorial</a></li>
713 <li><a href="http://felix.apache.org/site/ipojo-advanced-tutorial.html" title="iPOJO Advanced Tutorial">iPOJO Advanced Tutorial</a></li>
714 <li><a href="http://felix.apache.org/site/ipojo-composition-tutorial.html" title="iPOJO Composition Tutorial">iPOJO Composition Tutorial</a></li>
715</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000716
717
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000718<h6><a name="ServiceRequirementHandler-UserGuide"></a><b>User Guide</b></h6>
719<ul>
720 <li><a href="http://felix.apache.org/site/describing-components.html" title="Describing components">Describing components (handler list) </a></li>
721 <li><a href="http://felix.apache.org/site/using-xml-schemas.html" title="Using XML Schemas">Using XML Schemas</a></li>
722 <li><a href="http://felix.apache.org/site/apache-felix-ipojo-testing-components.html" title="apache-felix-ipojo-testing-components">Testing components</a></li>
723 <li><a href="http://felix.apache.org/site/ipojo-advanced-topics.html" title="iPOJO Advanced Topics">Advanced Topics</a></li>
724 <li><a href="http://felix.apache.org/site/ipojo-faq.html" title="iPOJO FAQ">FAQ</a></li>
725</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000726
727
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000728<h6><a name="ServiceRequirementHandler-Tools"></a><b>Tools</b></h6>
729<ul>
730 <li><a href="http://felix.apache.org/site/ipojo-eclipse-plug-in.html" title="iPOJO Eclipse Plug-in">iPOJO Eclipse Plug-in</a></li>
731 <li><a href="http://felix.apache.org/site/ipojo-ant-task.html" title="iPOJO Ant Task">iPOJO Ant Task</a></li>
732 <li><a href="http://felix.apache.org/site/ipojo-maven-plug-in.html" title="iPOJO Maven Plug-in">iPOJO Maven Plug-in</a></li>
733 <li><a href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html" title="apache-felix-ipojo-junit4osgi">Junit4OSGi</a></li>
734 <li><a href="http://felix.apache.org/site/ipojo-concepts-overview.html" title="iPOJO Concepts Overview">iPOJO concepts overview</a></li>
735</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000736
737
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000738<h6><a name="ServiceRequirementHandler-DeveloperGuide"></a><b>Developer Guide</b></h6>
739<ul>
740 <li>API: <span class="nobr"><a href="http://people.apache.org/%7Eclement/ipojo/api/1.0/" title="Visit page outside Confluence" rel="nofollow">1.0<sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span></li>
741 <li><a href="http://felix.apache.org/site/how-to-write-your-own-handler.html" title="How to write your own handler">How to write your own handler</a></li>
742 <li><a href="http://felix.apache.org/site/how-to-use-ipojo-manipulation-metadata.html" title="How to use iPOJO Manipulation Metadata">How to use iPOJO Manipulation Metadata</a></li>
743 <li><a href="http://felix.apache.org/site/dive-into-the-ipojo-manipulation-depths.html" title="Dive into the iPOJO Manipulation depths">Dive into the iPOJO Manipulation depths</a></li>
744</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000745
746
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000747<h6><a name="ServiceRequirementHandler-Misc&amp;Contact"></a><b>Misc &amp; Contact</b></h6>
748<ul>
749 <li><a href="http://felix.apache.org/site/apache-felix-ipojo-issuestracker.html" title="apache-felix-ipojo-issuestracker">Issues Tracker</a></li>
750 <li><a href="http://felix.apache.org/site/apache-felix-ipojo-supportedvms.html" title="apache-felix-ipojo-supportedVMs">Supported JVMs</a></li>
751 <li><a href="http://felix.apache.org/site/apache-felix-ipojo-supportedosgi.html" title="apache-felix-ipojo-supportedOSGi">Supported OSGi Implementations</a></li>
752 <li><span class="nobr"><a href="http://ipojo-dark-side.blogspot.com/" title="Visit page outside Confluence" rel="nofollow">iPOJO's Dark Side Blog<sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span></li>
753 <li><a href="http://felix.apache.org/site/future-ideas.html" title="Future Ideas">Future Ideas</a></li>
754 <li><a href="http://felix.apache.org/site/contact.html" title="Contact">Contact</a></li>
755 <li><a href="http://felix.apache.org/site/related-works.html" title="Related Works">Related Works</a></li>
756 <li><a href="http://felix.apache.org/site/article-presentations.html" title="Article &amp; Presentations">Article &amp; Presentations</a></li>
757</ul>
Clement Escoffier50254022008-05-16 20:33:54 +0000758
759
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000760<hr>
761<div class="" align="center">
762<p><span class="nobr"><a href="http://cwiki.apache.org/confluence/createrssfeed.action?types=blogpost&amp;statuses=created&amp;statuses=modified&amp;spaces=FELIX&amp;labelString=iPOJO&amp;rssType=atom&amp;maxResults=10&amp;timeSpan=5&amp;publicFeed=true&amp;title=iPOJO%20Atom%20Feed" title="Stay tuned!" rel="nofollow"><img src="service-requirement-handler_files/feed-icon-32x32.png" align="absmiddle" border="0"><sup><img class="rendericon" src="service-requirement-handler_files/linkext7.gif" alt="" align="absmiddle" border="0" width="7" height="7"></sup></a></span></p></div>
Clement Escoffier50254022008-05-16 20:33:54 +0000763
Clement Escoffier3e0db1e2009-01-15 15:35:17 +0000764<script type="text/javascript">
765var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
766document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
767</script><script src="service-requirement-handler_files/ga.js" type="text/javascript"></script>
768<script type="text/javascript">
769var pageTracker = _gat._getTracker("UA-1518442-4");
770pageTracker._trackPageview();
771</script>
772</td></tr></tbody></table>
773 </div>
774 </body></html>