blob: dec0d0ca6c921b94d33c6b199ae88f21d6c916f3 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE- 2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<head>
<title>Apache Felix - Service Binding Interceptors</title>
<link rel="icon" href="/res/favicon.ico">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="The most powerful component model for OSGi">
<link href="/ipojo/web/bootstrap/css/bootstrap-cerulean.css" rel="stylesheet">
<link href="/ipojo/web/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
<link href="/ipojo/web/bootstrap/css/font-awesome.min.css" rel="stylesheet">
<link href="/ipojo/web/style.css" rel="stylesheet">
<!-- Overide alert's colors -->
<link href="/ipojo/web/bootstrap/css/alert.css" rel="stylesheet">
<link rel="stylesheet" href="/ipojo/web/github.css" type="text/css" media="all">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="/ipojo/web/bootstrap/js/bootstrap.min.js"></script>
</head>
<body data-spy="scroll" data-target=".subnav">
<div class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="/documentation/subprojects/apache-felix-ipojo.html">Apache Felix iPOJO</a>
<div class="nav-collapse" id="main-menu">
<ul class="nav" id="main-menu-left">
<li><a href="/documentation/subprojects/apache-felix-ipojo/ipojo-news.html">News</a></li>
<li><a href="http://felix.apache.org/downloads.cgi">Downloads</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Tutorials <b class="caret"></b></a>
<ul class="dropdown-menu" id="tutorials-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-why-choose-ipojo.html">Why choose iPOJO</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-successstories.html">Success stories</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-feature-overview.html">Features</a></li>
<li class="divider"></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-in-10-minutes.html">iPOJO in 10 minutes</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/how-to-use-ipojo-annotations.html">Using Annotations</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-hello-word-maven-based-tutorial.html">Maven tutorial</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-advanced-tutorial.html">Advanced tutorial</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/apache-felix-ipojo-dosgi.html">Using Distributed OSGi</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-composition-tutorial.html">Application Composition</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Documentation <b class="caret"></b></a>
<ul class="dropdown-menu" id="user-guide-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/service-requirement-handler.html">Requiring a service</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/providing-osgi-services.html">Providing a service</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/lifecycle-callback-handler.html">Lifecycle management</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/configuration-handler.html">Configuration</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/architecture-handler.html">Introspection</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/controller-lifecycle-handler.html">Impacting the lifecycle</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/injecting-bundle-context.html">Accessing the Bundle Context</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/apache-felix-ipojo-instances.html">Creating instances</a></li>
<li class="divider"></li>
<li class="dropdown-submenu">
<a tabindex="-1" href="#">External <em>handlers</em></a>
<ul class="dropdown-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/event-admin-handlers.html">Asynchronous communication</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/ipojo-jmx-handler.html">JMX management</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/extender-pattern-handler.html">Extender pattern</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/white-board-pattern-handler.html">Whiteboard pattern</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/temporal-service-dependency.html">Temporal dependencies</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Configuration Admin &amp; Factories</a>
<ul class="dropdown-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/combining-ipojo-and-configuration-admin.html">iPOJO and config admin</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/ipojo-factory-service.html">Using the iPOJO Factory service</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/how-to-use-ipojo-factories.html">Factories and Instances</a></li>
</ul>
</li>
<li class="divider"></li>
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Advanced topics</a>
<ul class="dropdown-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/instance-vs-service-controller.html">Instance vs. Service Controllers</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/service-binding-interceptors.html">Service Binding Interceptors</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/using-xml-schemas.html">XML Schemas</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/apache-felix-ipojo-api.html">Using the iPOJO API</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/constructing-pojo-objects-with-factory-methods.html">Constructing service objects with factory methods</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/using-ipojo-introspection-api.html">Using the introspection API</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-testing-components.html">Testing components</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/using-stereotypes.html">Using @Stereotypes</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-eclipse-integration.html">Eclipse Integration</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/ipojo-extender-configuration.html">Configuring iPOJO's Extender</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-faq.html">FAQ</a></li>
<li class="divider"></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-write-your-own-handler.html">Handler development</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-use-ipojo-manipulation-metadata.html">Manipulation Metadata </a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-devguide/dive-into-the-ipojo-manipulation-depths.html">Dive into the iPOJO Manipulation depths</a></li>
<li><a href="http://felix.apache.org/ipojo/api/1.12.1">Javadoc</a></li>
</ul>
</li>
</ul>
</li>
<li class="dropdown" id="tools-menu">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Tools <b class="caret"></b></a>
<ul class="dropdown-menu" id="swatch-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-tools/ipojo-ant-task.html">Ant Task</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-tools/ipojo-maven-plug-in.html">Maven Plugin</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-tools/ipojo-arch-command.html">Architecture commands</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-tools/apache-felix-ipojo-online-manipulator.html">Online Manipulator</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-tools/ipojo-webconsole-plugin.html">Webconsole plugin</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-tools/ipojo-karaf-feature.html">Apache Karaf Features</a></li>
</ul>
</li>
<li class="dropdown" id="community-menu">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Community <b class="caret"></b></a>
<ul class="dropdown-menu" id="swatch-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/ipojo-support.html">Support</a></li>
<li><a href="http://www.apache.org/">ASF</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">Sponsors</a></li>
</ul>
</li>
<li class="dropdown" id="misc-menu">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Misc <b class="caret"></b></a>
<ul class="dropdown-menu" id="swatch-menu">
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-supportedvms.html">Supported JVMs</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-supportedosgi.html">Supported OSGi Implementations</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/articles-and-presentations.html">Article & Presentations</a></li>
<li><a href="/documentation/subprojects/apache-felix-ipojo/developing-camel-mediators-with-ipojo.html">Developping Camel mediators with iPOJO</a></li>
</ul>
</li>
</ul>
<ul class="nav pull-right" id="main-menu-right">
<li><a rel="tooltip" target="_blank" href="http://felix.apache.org">Apache Felix <i class="icon-share-alt"></i></a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div class="content">
<style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
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>
<h1 id="service-binding-interceptors">Service Binding Interceptors<a class="headerlink" href="#service-binding-interceptors" title="Permanent link">&para;</a></h1>
<p>Service Bindings are the connection between a service consumer and a service provider. Following the service-orientation paradigm (<em>publication-lookup-binding</em>), bindings are woven based a <em>local</em> analysis only: the consumer tracks and chooses the service to user. However, this <em>locality</em> avoids using more global knowledge to resolve the dependencies.</p>
<p>Service binding interceptors allows you to customize the service bindings from outside the involved components (providers or consumers). It let you adapt the bindings dynamically without touching anything in your component implementation.</p>
<div class="toc">
<ul>
<li><a href="#service-binding-interceptors">Service Binding Interceptors</a><ul>
<li><a href="#whats-an-interceptor">What's an interceptor</a></li>
<li><a href="#service-dependency-theory">Service dependency theory</a></li>
<li><a href="#selection-of-service-dependencies">Selection of service dependencies</a></li>
<li><a href="#service-tracking-interceptors">Service Tracking Interceptors</a></li>
<li><a href="#service-ranking-interceptors">Service Ranking Interceptors</a></li>
<li><a href="#binding-service-interceptors">Binding Service Interceptors</a></li>
</ul>
</li>
</ul>
</div>
<h2 id="whats-an-interceptor">What's an interceptor<a class="headerlink" href="#whats-an-interceptor" title="Permanent link">&para;</a></h2>
<p>Interceptors are services exposed in the OSGi service registry. They can be iPOJO components, but it's not a necessity. </p>
<p>Each interceptor can manage a set of dependencies. The interceptor selects this set with a LDAP filter, exposed as service properties (named <code>target</code>):</p>
<div class="codehilite"><pre><span class="nd">@Component</span><span class="o">(</span><span class="n">immediate</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="nd">@Provides</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AddLocationTrackingInterceptor</span> <span class="kd">extends</span> <span class="n">DefaultServiceTrackingInterceptor</span> <span class="o">{</span>
<span class="nd">@ServiceProperty</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">target</span> <span class="o">=</span> <span class="s">&quot;(dependency.id=foo)&quot;</span><span class="o">;</span>
<span class="c1">//...</span>
<span class="o">}</span>
</pre></div>
<p>The properties on which the filter can rely are explained below.</p>
<p>There are several types of interceptors:</p>
<ul>
<li><a href="http://felix.apache.org/ipojo/api/1.12.1/org/apache/felix/ipojo/dependency/interceptors/ServiceTrackingInterceptor.html">Tracking interceptors</a> - decide whether a service can be seen by a service dependency, and can <em>transform</em> service references</li>
<li><a href="http://felix.apache.org/ipojo/api/1.12.1/org/apache/felix/ipojo/dependency/interceptors/ServiceRankingInterceptor.html">Ranking interceptors</a> - select and sort service references accepted by the tracking interceptors</li>
<li><a href="http://felix.apache.org/ipojo/api/1.12.1/org/apache/felix/ipojo/dependency/interceptors/ServiceBindingInterceptor.html">Binding interceptors</a> - can modify the injected service objects</li>
</ul>
<p>For all these classes, default implementations are available in (http://felix.apache.org/ipojo/api/1.12.1/org/apache/felix/ipojo/dependency/interceptors/package-summary.html).</p>
<h2 id="service-dependency-theory">Service dependency theory<a class="headerlink" href="#service-dependency-theory" title="Permanent link">&para;</a></h2>
<p>Before looking more deeply into these interceptors, let's first explain the service dependency principle. Before being injected inside the component's code, a service (reference) traverses a set of layers. The service dependencies consider all services from the service registry and narrows this set to select the right set of services. The narrowing process has three phases.</p>
<p>The initial set of services considered by the service dependencies is named <em>base set</em>. It contains all services from the service registry providing the requested service interface.</p>
<p>Then, for all services from the base set, the tracking interceptors (handling the service dependency) can decide whether or not to accept the service. By this way, they can decide to hide services. They are also able to <em>transform</em> services, to add and/or remove service properties. Several tracking interceptors can handle the same service dependency. They are invoked sequentially. Service accepted by all tracking interceptors are composed the <em>matching set</em>. Notice that the OSGi LDAP filters are tracking interceptors.</p>
<p><img src="narrowing.png"/></p>
<p>Unlike service tracking interceptors, only one ranking interceptor can be plugged on a service dependency. The ranking interceptor transforms the matching set to the <em>selected set</em> by selecting and sorting services. The iPOJO comparator feature is a ranking interceptor. Notice that ranking interceptor may select an empty set from the matching set. </p>
<p>Finally, the last layer is the binding interceptor. This layer does not narrow the service set, but may interceptor the <em>weaving</em> of the binding for monitoring or interception purposes.</p>
<h2 id="selection-of-service-dependencies">Selection of service dependencies<a class="headerlink" href="#selection-of-service-dependencies" title="Permanent link">&para;</a></h2>
<p>All interceptors must publish a <em>target</em> service property indicating the set of service dependency they handle. This property is an LDAP filter that can rely on the following properties:</p>
<ul>
<li><em>instance.name</em> : to select all dependencies of a specific instance (String)</li>
<li><em>instance.state</em> : to filter on the instance state (int)</li>
<li><em>factory.name</em> : to select all instances from a specific factory (String)</li>
<li><em>bundle.symbolicName</em> : to select the dependencies from all instances declared in a specific bundle (String)</li>
<li><em>bundle.version</em> : to refine the filter based on the bundle symbolic name with a version (String)</li>
<li><em>dependency.specification</em> : to select all dependencies looking for a specific interface (String)</li>
<li><em>dependency.id</em> : to select a dependency based on its identifier (String)</li>
<li><em>dependency.state</em> : to select a dependency based on the dependency state (int)</li>
<li><em>objectClass</em> : to select a dependency looking a a specific interface. This property also contains the inherited interfaces (String array)</li>
</ul>
<p>Let's see some examples:</p>
<ul>
<li>select all dependencies from an instance named <code>foo</code>: <code>(instance.name=foo)</code>.</li>
<li>select all invalid dependencies: <code>(dependency.state=0)</code></li>
<li>select all dependencies targeting the specification <code>LogService</code>: <code>(dependency.specification=o.o….LogService)</code></li>
<li>select the dependency <code>foo</code> from the instance <code>instance</code>:
<code>(&amp;(instance.name=instance)(dependency.id=foo))</code></li>
<li>select all dependencies targeting <code>AbstractService</code> or sub-classes: <code>(objectClass=o.o…AbstractService)</code></li>
</ul>
<h2 id="service-tracking-interceptors">Service Tracking Interceptors<a class="headerlink" href="#service-tracking-interceptors" title="Permanent link">&para;</a></h2>
<p>Service tracking interceptors are responsible for accepting matching services. Their main goal is to filter the <em>base set</em>. The following tracking interceptor hides all services with the <code>hidden</code> property:</p>
<div class="codehilite"><pre><span class="nd">@Component</span><span class="o">(</span><span class="n">immediate</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="nd">@Provides</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">HidingTrackingInterceptor</span> <span class="kd">extends</span> <span class="n">DefaultServiceTrackingInterceptor</span> <span class="o">{</span>
<span class="nd">@ServiceProperty</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">target</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">prop</span> <span class="o">=</span> <span class="s">&quot;hidden&quot;</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">TransformedServiceReference</span><span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">accept</span><span class="o">(</span><span class="n">DependencyModel</span> <span class="n">dependency</span><span class="o">,</span> <span class="n">BundleContext</span> <span class="n">context</span><span class="o">,</span>
<span class="n">TransformedServiceReference</span><span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">ref</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">ref</span><span class="o">.</span><span class="na">contains</span><span class="o">(</span><span class="n">prop</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">ref</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
<p>Such interceptor needs to be instantiated with a configuration specifying the <code>target</code> property.</p>
<p>Service Tracking Interceptors can also transform service references to add/remove service properties:</p>
<div class="codehilite"><pre><span class="nd">@Override</span>
<span class="kd">public</span> <span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">TransformedServiceReference</span><span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">accept</span><span class="o">(</span><span class="n">DependencyModel</span> <span class="n">dependency</span><span class="o">,</span>
<span class="n">BundleContext</span> <span class="n">context</span><span class="o">,</span> <span class="n">TransformedServiceReference</span><span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">ref</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">ref</span>
<span class="o">.</span><span class="na">addProperty</span><span class="o">(</span><span class="s">&quot;location&quot;</span><span class="o">,</span> <span class="s">&quot;kitchen&quot;</span><span class="o">)</span>
<span class="o">.</span><span class="na">removeProperty</span><span class="o">(</span><span class="s">&quot;hidden&quot;</span><span class="o">);</span>
<span class="o">}</span>
</pre></div>
<p>Tracking interceptors can decide to <em>invalidate</em> the matching set and ask to be re-evaluated. For example, a reconfigured interceptor must reevaluate all services from the base set:</p>
<div class="codehilite"><pre><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">set</span><span class="o">(</span><span class="n">String</span> <span class="n">newValue</span><span class="o">)</span> <span class="o">{</span>
<span class="n">prop</span> <span class="o">=</span> <span class="n">newValue</span><span class="o">;</span>
<span class="n">invalidateMatchingServices</span><span class="o">();</span>
<span class="o">}</span>
</pre></div>
<p>The <code>invalidateMatchingServices</code> invalidates the matching service set and triggers a complete evaluation of the base set.</p>
<p>Several tracking interceptors can manage the same dependency. All interceptors must accept matching services. The last evaluated tracking interceptor is the iPOJO LDAP filter.</p>
<h2 id="service-ranking-interceptors">Service Ranking Interceptors<a class="headerlink" href="#service-ranking-interceptors" title="Permanent link">&para;</a></h2>
<p>Service Ranking Interceptors receive the services from the matching set as input and returns a sorted sub-set. Unlike service tracking interceptors, only one ranking interceptor can manage a dependency.</p>
<div class="codehilite"><pre><span class="nd">@Component</span><span class="o">(</span><span class="n">immediate</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="nd">@Provides</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FilterRankingInterceptor</span> <span class="kd">extends</span> <span class="n">DefaultServiceRankingInterceptor</span> <span class="o">{</span>
<span class="nd">@ServiceProperty</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">target</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">Comparator</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">&gt;</span> <span class="n">comparator</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">FilterRankingInterceptor</span><span class="o">()</span> <span class="o">{</span>
<span class="n">comparator</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GradeComparator</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">&gt;</span> <span class="n">getServiceReferences</span><span class="o">(</span><span class="n">DependencyModel</span> <span class="n">dependency</span><span class="o">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">&gt;</span> <span class="n">matching</span><span class="o">)</span> <span class="o">{</span>
<span class="n">List</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">&gt;</span> <span class="n">references</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">&gt;();</span>
<span class="k">for</span> <span class="o">(</span><span class="n">ServiceReference</span> <span class="n">ref</span> <span class="o">:</span> <span class="n">matching</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">ref</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">&quot;grade&quot;</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="n">references</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">ref</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="n">Collections</span><span class="o">.</span><span class="na">sort</span><span class="o">(</span><span class="n">references</span><span class="o">,</span> <span class="n">comparator</span><span class="o">);</span>
<span class="k">return</span> <span class="n">references</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
<p>The <code>FilterRankingInterceptor</code> filters and ranks the matching services. First, it ignores all services without the <code>grade</code> property. Then, it sorts the remaining services using a <em>comparator</em>.</p>
<p>Notice that ranking interceptors can return an empty set. Unlike tracking interceptors, they process a set of services (the matching set).</p>
<p>When a ranking interceptors changes its ranking criteria, it can invalid the selected set with the <code>invalidateSelectedServices</code> method:</p>
<div class="codehilite"><pre><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">set</span><span class="o">(</span><span class="n">String</span> <span class="n">newValue</span><span class="o">)</span> <span class="o">{</span>
<span class="n">inverse</span> <span class="o">=</span> <span class="n">Boolean</span><span class="o">.</span><span class="na">parseBoolean</span><span class="o">(</span><span class="n">newValue</span><span class="o">);</span>
<span class="n">invalidateSelectedServices</span><span class="o">();</span>
<span class="o">}</span>
</pre></div>
<p>The iPOJO comparator is a ranking interceptor. As only one interceptor can manage the dependency, the comparator is replaced when an external interceptor is plugged. It is restored when the external interceptors disappears.</p>
<h2 id="binding-service-interceptors">Binding Service Interceptors<a class="headerlink" href="#binding-service-interceptors" title="Permanent link">&para;</a></h2>
<p>The last category of interceptors is bindings interceptors. They intercepts the binding weaving, and thus, can <em>change</em> the injected service objects. This kind of interceptors are often used to inject a proxy intercepting some invocations:</p>
<div class="codehilite"><pre><span class="nd">@Component</span>
<span class="nd">@Provides</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ProxyBindingInterceptor</span> <span class="kd">extends</span> <span class="n">DefaultDependencyInterceptor</span> <span class="kd">implements</span> <span class="n">ServiceBindingInterceptor</span> <span class="o">{</span>
<span class="nd">@ServiceProperty</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">target</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">deps</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">ServiceReference</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;();</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">S</span> <span class="n">getService</span><span class="o">(</span><span class="n">DependencyModel</span> <span class="n">dependency</span><span class="o">,</span> <span class="n">ServiceReference</span><span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">reference</span><span class="o">,</span> <span class="n">S</span> <span class="n">service</span><span class="o">)</span> <span class="o">{</span>
<span class="n">S</span> <span class="n">proxy</span> <span class="o">=</span> <span class="o">(</span><span class="n">S</span><span class="o">)</span> <span class="n">Proxy</span><span class="o">.</span><span class="na">newProxyInstance</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">getClassLoader</span><span class="o">(),</span>
<span class="k">new</span> <span class="n">Class</span><span class="o">[]{</span><span class="n">dependency</span><span class="o">.</span><span class="na">getSpecification</span><span class="o">()},</span> <span class="k">new</span> <span class="n">Interceptor</span><span class="o">(</span><span class="n">service</span><span class="o">));</span>
<span class="n">deps</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">reference</span><span class="o">,</span> <span class="n">proxy</span><span class="o">);</span>
<span class="k">return</span> <span class="n">proxy</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="kt">void</span> <span class="n">ungetService</span><span class="o">(</span><span class="n">DependencyModel</span> <span class="n">dependency</span><span class="o">,</span> <span class="n">ServiceReference</span><span class="o">&lt;</span><span class="n">S</span><span class="o">&gt;</span> <span class="n">reference</span><span class="o">)</span> <span class="o">{</span>
<span class="n">deps</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">reference</span><span class="o">);</span>
<span class="o">}</span>
</pre></div>
<p>Several binding intercepts can be plugged on the same service dependency, creating a chain of interception.</p>
</div>
</div>
<hr/>
<div class="container">
<footer id="footer">
<div class="row">
<div class="trademarkFooter span7">
Apache Felix, Felix, Apache, the Apache feather logo, and the Apache Felix project
logo are trademarks of The Apache Software Foundation. All other marks mentioned
may be trademarks or registered trademarks of their respective owners.
</div>
<div class="timestamp span3 offset2">
Rev. 1530248 by clement on Tue, 8 Oct 2013 12:13:27 +0000
</div>
</div>
</footer>
</div>
</body>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-1518442-4");
pageTracker._trackPageview();
} catch(err) {}
</script>
</html>