blob: 0bd2593a8478ff676e7859803fb108ab3ab848e8 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_172) on Tue Oct 09 13:57:04 CEST 2018 -->
<title>ServiceDependency</title>
<meta name="date" content="2018-10-09">
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
<script type="text/javascript" src="../../../../../../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="ServiceDependency";
}
}
catch(err) {
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../org/apache/felix/dm/annotation/api/package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../../../../org/apache/felix/dm/annotation/api/RepeatableProperty.html" title="annotation in org.apache.felix.dm.annotation.api"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.Any.html" title="interface in org.apache.felix.dm.annotation.api"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../../../../index.html?org/apache/felix/dm/annotation/api/ServiceDependency.html" target="_top">Frames</a></li>
<li><a href="ServiceDependency.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Required&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.optional.element.summary">Optional</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.element.detail">Element</a></li>
</ul>
</div>
<a name="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">org.apache.felix.dm.annotation.api</div>
<h2 title="Annotation Type ServiceDependency" class="title">Annotation Type ServiceDependency</h2>
</div>
<div class="contentContainer">
<div class="description">
<ul class="blockList">
<li class="blockList">
<hr>
<br>
<pre>@Retention(value=CLASS)
@Target(value={METHOD,FIELD})
public @interface <span class="memberNameLabel">ServiceDependency</span></pre>
<div class="block">Annotates a method or a field for injecting a Service Dependency. When applied on a class
field, optional unavailable dependencies are injected with a NullObject.
<p> For "add", "change", "remove" callbacks, the following method signatures are supported:
<pre><code>
(Component comp, ServiceReference ref, Service service)
(Component comp, ServiceReference ref, Object service)
(Component comp, ServiceReference ref)
(Component comp, Service service)
(Component comp, Object service)
(Component comp)
(Component comp, Map properties, Service service)
(ServiceReference ref, Service service)
(ServiceReference ref, Object service)
(ServiceReference ref)
(Service service)
(Service service, Map properties)
(Map properties, Service, service)
(Service service, Dictionary properties)
(Dictionary properties, Service service)
(Object service)
(ServiceReference&lt;T&gt; service)
(ServiceObjects&lt;T&gt; service)
</code></pre>
<p> For "swap" callbacks, the following method signatures are supported:
<pre><code>
(Service old, Service replace)
(Object old, Object replace)
(ServiceReference old, Service old, ServiceReference replace, Service replace)
(ServiceReference old, Object old, ServiceReference replace, Object replace)
(Component comp, Service old, Service replace)
(Component comp, Object old, Object replace)
(Component comp, ServiceReference old, Service old, ServiceReference replace, Service replace)
(Component comp, ServiceReference old, Object old, ServiceReference replace, Object replace)
(ServiceReference old, ServiceReference replace)
(Component comp, ServiceReference old, ServiceReference replace)
(ServiceObjects old, ServiceObjects replace)
(Component comp, ServiceObjects old, ServiceObjects replace)
</code></pre>
<p> When the dependency is injected on a class field, the following field types are supported:
<ul>
<li> a field having the same type as the dependency. If the field may be accessed by any thread, then the field should be declared volatile, in order to ensure visibility
when the field is auto injected concurrently.
<li> a field which is assignable to an Iterable&lt;T&gt; where T must match the dependency type. In this case, an Iterable will be injected by DependencyManager before the start
callback is called. The Iterable field may then be traversed to inspect the currently available dependency services. The Iterable can possibly be set to a final value
so you can choose the Iterable implementation of your choice (for example, a CopyOnWrite ArrayList, or a ConcurrentLinkedQueue).
<li> a Map&lt;K,V&gt; where K must match the dependency type and V must exactly equals Dictionary class. In this case, a ConcurrentHashMap will be injected by DependencyManager
before the start callback is called. The Map may then be consulted to lookup current available dependency services, including the dependency service properties
(the map key holds the dependency services, and the map value holds the dependency service properties). The Map field may be set to a final value so you can choose a Map of your choice (Typically a ConcurrentHashMap). A ConcurrentHashMap is "weakly consistent", meaning that when traversing the elements, you may or may not see any concurrent updates made on the map. So, take care to traverse the map using an iterator on the map entry set, which allows to atomically lookup pairs of Dependency service/Service properties.
</ul>
<h3>Usage Examples</h3>
Here, the MyComponent component is injected with a dependency over a "MyDependency" service
<blockquote><pre>
&#64;Component
class MyComponent {
&#64;ServiceDependency
volatile MyDependency dependency;
}
</pre></blockquote>
The dependency can also be injected using a method callback:
<blockquote><pre>
&#64;Component
class MyComponent {
&#64;ServiceDependency
void bind(MyDependency dependency) {}
}
</pre></blockquote>
Same example as before, but the callback signatures includes service properties:
<blockquote><pre>
&#64;Component
class MyComponent {
&#64;ServiceDependency
void bind(MyDependency dependency, Map&lt;String, Object&gt; serviceProperties) {}
}
</pre></blockquote>
Another example, were we inject multiple dependencies to an Iterable field
<blockquote><pre>
&#64;Component
class MyComponent {
&#64;ServiceDependency
final Iterable&lt;Dependency&gt; dependencies = new CopyOnWriteArrayList&lt;&gt;();
}
</pre></blockquote>
Another example, were we inject multiple dependencies to a Map field, allowing to inspect service dependency properties
(the keys hold the services, and the values hold the associated service properties):
<blockquote><pre>
&#64;Component
class MyComponent {
&#64;ServiceDependency
final Map&lt;MyDependency, Dictionary&lt;String, Object&gt;&gt; dependencies = new ConcurrentHashMap&lt;&gt;;
}
</pre></blockquote></div>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- =========== ANNOTATION TYPE OPTIONAL MEMBER SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="annotation.type.optional.element.summary">
<!-- -->
</a>
<h3>Optional Element Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Optional Element Summary table, listing optional elements, and an explanation">
<caption><span>Optional Elements</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Optional Element and Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#added--">added</a></span></code>
<div class="block">The callback method to be invoked when the service is available.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#changed--">changed</a></span></code>
<div class="block">The callback method to be invoked when the service properties have changed.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>java.lang.Class&lt;?&gt;</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#defaultImpl--">defaultImpl</a></span></code>
<div class="block">Sets the default implementation for an <code>optional</code> service dependency.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#filter--">filter</a></span></code>
<div class="block">The Service dependency OSGi filter.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#name--">name</a></span></code>
<div class="block">The name used when dynamically configuring this dependency from the init method.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#propagate--">propagate</a></span></code>
<div class="block">Returns true if the dependency service properties must be published along with the service.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#removed--">removed</a></span></code>
<div class="block">The callback method to invoke when the service is lost.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#required--">required</a></span></code>
<div class="block">Whether the Service dependency is required or not.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>java.lang.Class&lt;?&gt;</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#service--">service</a></span></code>
<div class="block">The type if the service this dependency is applying on.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>java.lang.String</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#swap--">swap</a></span></code>
<div class="block">the method to call when the service was swapped due to addition or removal of an aspect</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>long</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#timeout--">timeout</a></span></code>
<div class="block">The max time in millis to wait for the dependency availability.</div>
</td>
</tr>
</table>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ ANNOTATION TYPE MEMBER DETAIL =========== -->
<ul class="blockList">
<li class="blockList"><a name="annotation.type.element.detail">
<!-- -->
</a>
<h3>Element Detail</h3>
<a name="service--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>service</h4>
<pre>public abstract&nbsp;java.lang.Class&lt;?&gt;&nbsp;service</pre>
<div class="block">The type if the service this dependency is applying on. By default, the method parameter
(or the class field) is used as the type. If you want to match all available services, you can set
this attribute to the <a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.Any.html" title="interface in org.apache.felix.dm.annotation.api"><code>ServiceDependency.Any</code></a> class. In this case, all services (matching the <a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.html#filter--"><code>filter()</code></a> attribute if it is specified) will
be returned.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the service dependency</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>java.lang.Object.class</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="filter--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>filter</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;filter</pre>
<div class="block">The Service dependency OSGi filter.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the service filter</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>""</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="defaultImpl--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>defaultImpl</h4>
<pre>public abstract&nbsp;java.lang.Class&lt;?&gt;&nbsp;defaultImpl</pre>
<div class="block">Sets the default implementation for an <code>optional</code> service dependency. You can use this to supply
your own implementation that will be used instead of a Null Object when the dependency is
not available. This is also convenient if the service dependency is not an interface
(which would cause the Null Object creation to fail) but a class.
Only use this attribute on an optional service dependency applied on a class field.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the default implementation class</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>java.lang.Object.class</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="required--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>required</h4>
<pre>public abstract&nbsp;boolean&nbsp;required</pre>
<div class="block">Whether the Service dependency is required or not. When the dependency is optional and if the annotation is declared on a class field, then
a Null Object will be injected in case the dependency is unavailable.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the required flag</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>true</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="added--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>added</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;added</pre>
<div class="block">The callback method to be invoked when the service is available. This attribute is only meaningful when
the annotation is applied on a class field.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the add callback</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>""</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="changed--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>changed</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;changed</pre>
<div class="block">The callback method to be invoked when the service properties have changed.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the change callback</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>""</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="removed--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>removed</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;removed</pre>
<div class="block">The callback method to invoke when the service is lost.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the remove callback</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>""</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="swap--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>swap</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;swap</pre>
<div class="block">the method to call when the service was swapped due to addition or removal of an aspect</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the swap callback</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>""</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="timeout--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>timeout</h4>
<pre>public abstract&nbsp;long&nbsp;timeout</pre>
<div class="block">The max time in millis to wait for the dependency availability.
Specifying a positive number allow to block the caller thread between service updates. Only
useful for required stateless dependencies that can be replaced transparently.
A Dynamic Proxy is used to wrap the actual service dependency (which must be an interface).
When the dependency goes away, an attempt is made to replace it with another one which satisfies
the service dependency criteria. If no service replacement is available, then any method invocation
(through the dynamic proxy) will block during a configurable timeout. On timeout, an unchecked
<code>IllegalStateException</code> exception is raised (but the service is not deactivated).<p>
Notice that the changed/removed callbacks are not used when the timeout parameter is greater than -1.
-1 means no timeout at all (default). 0 means that invocation on a missing service will fail
immediately. A positive number represents the max timeout in millis to wait for the service availability.
Sample Code:
<blockquote><pre>
&#64;Component
class MyServer implements Runnable {
&#64;ServiceDependency(timeout=15000)
MyDependency dependency;.
&#64;Start
void start() {
(new Thread(this)).start();
}
public void run() {
try {
dependency.doWork();
} catch (IllegalStateException e) {
t.printStackTrace();
}
}
</pre></blockquote></div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the wait time when the dependency is unavailable</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>-1L</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="name--">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>name</h4>
<pre>public abstract&nbsp;java.lang.String&nbsp;name</pre>
<div class="block">The name used when dynamically configuring this dependency from the init method.
Specifying this attribute allows to dynamically configure the dependency
<code>filter</code> and <code>required</code> flag from the Service's init method.
All unnamed dependencies will be injected before the init() method; so from the init() method, you can
then pick up whatever information needed from already injected (unnamed) dependencies, and configure dynamically
your named dependencies, which will then be calculated once the init() method returns.
<p> See <a href="../../../../../../org/apache/felix/dm/annotation/api/Init.html" title="annotation in org.apache.felix.dm.annotation.api"><code>Init</code></a> annotation for an example usage of a dependency dynamically configured from the init method.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>the dependency name used to dynamically configure the filter and required flag from the init callback.</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>""</dd>
</dl>
</li>
</ul>
</li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="propagate--">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>propagate</h4>
<pre>public abstract&nbsp;boolean&nbsp;propagate</pre>
<div class="block">Returns true if the dependency service properties must be published along with the service.
Any additional service properties specified directly are merged with these.
The component provided service properties take precedence over the propagated service dependency properties, meaning
that a give component service property overrides the same property included in the propagated service dependency properties.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>true if dependency service properties must be published along with the service, false if not.</dd>
</dl>
<dl>
<dt>Default:</dt>
<dd>false</dd>
</dl>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../org/apache/felix/dm/annotation/api/package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../../../../org/apache/felix/dm/annotation/api/RepeatableProperty.html" title="annotation in org.apache.felix.dm.annotation.api"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../../../../org/apache/felix/dm/annotation/api/ServiceDependency.Any.html" title="interface in org.apache.felix.dm.annotation.api"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../../../../index.html?org/apache/felix/dm/annotation/api/ServiceDependency.html" target="_top">Frames</a></li>
<li><a href="ServiceDependency.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Required&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.optional.element.summary">Optional</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#annotation.type.element.detail">Element</a></li>
</ul>
</div>
<a name="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>