The extender pattern handler
The objective of this handler is to simplify the development of extender-based architecture. This architecture-style is based on two different roles:
- The extender
- The extensions
The Extender pattern
This architecture-style is based on two different roles:
- The extender
- The extension

The relation is basically a 1..n relation. The extender tracks
extensions. The particularity of this architecture-style is that
extensions are packaged in different bundles. An extension is detected
by analyzing the bundle. Indeed these bundles can have a special mark
in their manifest of a special file...
Implementing an extender pattern could be complex as the extender needs
to track these marks dynamically. When a bundle starts, it needs to
look at the mark. Then a bundle leave, the extender must release all
object created from this bundle.
This handler tracks bundle for you based on the specified required
mark. At each time a matching bundle appears or disappears, a callback
is invoked. The mark is currently a header in the bundle manifest.
Nowadays, a lot of frameworks use this pattern such as iPOJO it-self
(to find both bundles containing components and bundles adding a new
implementation type), Spring-DM ...
Using the handler
First of all, you need to configure the component type to use the handler such as:
| <iPOJO xmlns:extender="org.apache.felix.ipojo.extender"> | 
| <component | 
| classname="org.apache.felix.ipojo.extender.myextender"> | 
| <!-- Extender Pattern handler configuration --> | 
| <extender:extender | 
| extension="My-Extension" | 
| onArrival="onBundleArrival" | 
| onDeparture="onBundleDeparture" | 
| /> | 
| <callback transition="invalidate" method="stopping" /> | 
| <callback transition="validate" method="starting" /> | 
| <provides /> | 
| </component> | 
| </iPOJO> | 
Notice that, this handler is an external handler. So, it uses the "org.apache.felix.ipojo.extender" namespace.
Once described, you can implement your component. The methods specified
methods will be called when a matching bundle arrives or leaves.
In the previous example, these methods could be: 
| void onBundleArrival(Bundle bundle, String header) { | 
| // Do something | 
| } | 
| void onBundleDeparture(Bundle bundle) { | 
| // Do something | 
| } | 
Notice the different signatures of the methods. The arrival method is called with the arriving bundle and the matching header value (i.e. the value of the My-Extension header of the bundle manifest). The departure method just receives the leaving bundle.
Configuration
The handler has only three mandatory attributes:
- Extension: declaring the looked manifest header.
- onArrival: declaring the method to invoke when a matching bundle arrives
- onDeparture: declaring the method to invoke when a matching bundle leaves
 Called despite being invalid
 Called despite being invalid
	Download
The handler is available on the download page.
Sources are available on the Felix trunk at the following location: http://svn.apache.org/repos/asf/felix/trunk/ipojo/handler/extender/
Configuring the handler with annotations
It is possible to configure the handler with a simple annotation available in the annotation pack ('annotation' project in the iPOJO trunk). Here is an example of usage:
| import org.apache.felix.ipojo.annotations.Component; | 
| import org.osgi.framework.Bundle; | 
| @Component | 
| @org.apache.felix.ipojo.extender.Extender(extension="foo", onArrival="onArrival", onDeparture="onDeparture") | 
| public class Extender { | 
| public void onArrival(Bundle bundle, String foo) { | 
| // do something | 
| } | 
| public void onDeparture(Bundle bundle) { | 
| // do something | 
| } | 
| } | 
The extension attribute allows setting the bundle filter.
A more realistic example
The Junit4OSGi framework, available here
, uses this handler to track Junit Test Suite offered by the installed
bundles. The Junit4Osgi bundle has a component using this handler to be
notified when a bundle with the Test-Suite header appears or leaves.


 

