felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmesc...@apache.org
Subject svn commit: r1421893 [11/24] - in /felix/site/trunk/content: ./ documentation/ documentation/community/ documentation/development/ documentation/faqs/ documentation/subprojects/ documentation/subprojects/apache-felix-commons/ documentation/subprojects/...
Date Fri, 14 Dec 2012 14:30:22 GMT
Added: felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/event-admin-handlers.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/event-admin-handlers.mdtext?rev=1421893&view=auto
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/event-admin-handlers.mdtext (added)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/event-admin-handlers.mdtext Fri Dec 14 14:29:22 2012
@@ -0,0 +1,271 @@
+Title: Event Admin Handlers
+
+{include:apache-felix-ipojo-header}
+
+<div class="content">
+
+
+# Event Admin Handlers
+
+*The goal of the Event Admin Handlers is to allow event communications between iPOJO component instances. The implementation of these handlers relies on an event admin services. It enables the iPOJO component to listen to a list of topics and to receive all related events. It also allows components to send events in an easy way.*
+
+{div:class=toc}
+[TOC]
+{div}
+
+<div class="info" markdown="1">
+**change in the 1.2.0**
+The 1.2.0 version use the namespace : `org.apache.felix.ipojo.handlers.event` instead of `org.apache.felix.ipojo.handlers.event.EventAdminHandler`.
+</div>
+
+<div class="info" markdown="1">
+**change in the 1.7.0**
+The `@Publisher` annotation is now deprecated and replaced by `@Publishes`.
+</div>
+
+## An example
+Hereafter is presented a small example :
+
+    @Component
+    @Instantiate
+    public class MyComponent {
+        
+        @Publishes( // or @Publisher before the 1.7.0
+    	  name="myPublisher",
+          topics="bar,nuts") 
+        private Publisher m_publisher;
+    
+        @Subscriber(
+          name="mySubscriber",
+          topics="foo")
+        public void receive(Event e) {
+           // Event received
+           // Do something with the event
+        }
+    }
+
+
+This component can also be described using the XML formalism:
+
+    <ipojo
+        xmlns:ev="org.apache.felix.ipojo.handlers.event">
+    	<component className="...MyComponent">
+    		<ev:subscriber
+    			name="mySubscriber"
+    			callback="receive"
+    			topics="foo"/>
+    		<ev:publisher
+    			name="myPublisher"
+    			field="m_publisher"
+    			topics="bar,nuts"/>
+    	</component>
+    	<instance component="...MyComponent"/>
+    </ipojo>
+
+
+In XML, you need to specify the namespace of the Handler. You can find here one event subscriber (named mySubscriber) and one event publisher (named myPublisher). In these handler configurations, the name parameter is mandatory. The topics parameter is optional as it can be specified in the instance configuration. The callback parameter of the mySubscriber element is mandatory and indicates the method that handles received events. In this case, this method must have a single argument of type org.osgi.service.event.Event. The field parameter of the myPublisher element indicates the field (of type org.apache.felix.ipojo.handlers.event.publisher.Publisher) that is used by the POJO to send events on the specified topics. All type compliance will be checked by the handler at component instantiation time.
+
+## Download
+
+The event admin handlers (to send and receive events) are available in the Felix trunk in the iPOJO project. See the [Download]({{ refs.download.path }}) page to download and compile these sources.
+
+## How does it work?
+
+The handler will parse the description provided in the metadata, and register for you the EventHandler in the OSGi Registry. On one hand, your POJO will receive each event through the handler. With this handler you can specify different callback methods for different topics. On the other side, the handler instantiates and injects configured Publisher references in your POJO, so you can send events transparently through these publishers.
+
+## EventHandler Specification
+
+Here you can find all configuration options of the EventAdmin handler. As seen before, the handler contains two components : the event subscriber and the event publisher. These components can be configured, using several attributes, as described below. Some of these attributes can be (re)defined in the instance configuration.
+
+*Handler namespace :* org.apache.felix.ipojo.handlers.event
+
+### Event subscriber attributes
+{div:class=borderedTable}
+| Attribute name | Required | Description |
+|--|--|--|
+| *name* | YES | The name of the event subscriber, acting as a unique 			identifier. |
+| *callback* | YES | The name of the POJO's method that will be called each time an 			event is received. This method takes only one parameter, of typeorg.osgi.service.event.Eventby default, but this type can be overridden by defining the 			data-key and/or the data-type attributes. |
+| *topics* | YES\* | The comma-separated-list of the topics that the handler will 			listen to. Each event sent on a topic present in this list will be 			sent to the specified callback method. |
+  
+  
+  
+  
+  
+  
+If an event is received and it does not contain such a key, it 			is ignored (with a warning message). |
+  
+  
+Data events that are not corresponding to the specified type 			will be ignored (with a warning message). |
+| *filter* | NO\* | The event filter is used to filter incoming events before 			sending them to the callback. The syntax of this field is 			described in the OSGi EventAdmin Specification. If you don't 			specify a filter, all events sent on the listened topics will be 			considered. |
+\* These attributes can be (re)defined in the instance configuration.
+{div}
+### Event publisher attributes
+{div:class=borderedTable}
+| Attribute name | Required | Description |
+|--|--|--|
+| *name* | YES | The name of the event publisher, acting as a unique identifier. |
+| *field* | YES | The name of the POJO's field that will be used to send events. 			The field is initialized at component instantiation time. The type 			of the field must be : org.apache.felix.ipojo.handlers.event.publisher.Publisher. Despite it creates a dependency between the component code and the handler, this system allows hiding the 			whole complexity of event sending. |
+| *topics* | YES\* | The comma-separated-list of the topics on which events will be sent. |
+  
+  
+The default value of this attribute is user.data. |
+  
+  
+The default value of this attribute is "false". |
+\* These attributes can be (re)defined in the instance configuration.
+{div}
+### Instance configuration
+
+Some of the described attributes can be (re)defined in the instance configuration section of your metadata file. Its permits to configure event management instance by instance. The following properties are used by the handler :
+* *event.topics* : overrides *topics* attribute, 	available for both subscribers and publishers configuration
+* *event.filter* : overrides *filter* attribute, 	available for subscribers configuration only.
+
+### Publisher interface
+
+The Publisher interface is the link between the component code and the handler. It permits to publish events on the topics specified in the component's description (or instance configuration). The implemented methods are :
+* public void send{color:#000000}(Dictionary 	content);{color}
+This method is used to send a 	standard event, with the specified content. Some specific properties 	may be added in the content to satisfy EventAdmin specification. 	(e.g., event.topic).
+* public void sendData{color:#000000}(Object 	o);{color}
+This method is the easier way to send 	data. The given object is placed in the event dictionary according 	to the *data-key* attribute (or its default value). Then, this 	dictionary is sent as a normal event.
+
+## Handler Architecture
+
+Here is shown the global architecture of the EventHandler : the interactions between the user components (i.e., POJO), the handler and the OSGi runtime environment.
+
+!handler-arch.png!
+
+## EventHandler Features
+In this section, you will find some examples of the handler's features.
+
+### Instance customization
+As described in the 'Instance configuration' section, you can (re)define some of the subscribers or publishers attributes. You can notice that required attributes that are not defined in the component description must be defined in the instance configuration section. Hereafter is an example of an instance configuration of this handler :
+
+    <ipojo>
+    	<instance component="...MyComponent">
+    		<property name="event.topics">
+    			<property name="mySubscriber" value="foo"/>
+    			<property name="myPublisher" value="bar,nuts"/>
+    		</property>
+    		<property name="event.filter">
+    			<property name="mySubscriber"
+    				    value="|((arg=Minibar)(arg=Coconuts))"/>
+    		</property>
+    	</instance>
+    </ipojo>
+
+
+### Data events
+One of the most important features of the EventHandler is the capability of sending and receiving data events. You may know that the OSGi EventAdmin Service allows bundles to send custom objects in events, inserting them in the event's dictionary. The EventHandler hides the dictionary manipulation and allows iPOJO components to receive custom objects at any time.
+
+First, you have define the *data-key* attribute in the publisher configuration (`dataKey` in annotations). Sent objects will be contained in the event dictionary and are accessible with the "user.data" key. 
+
+
+    <ipojo
+        xmlns:ev="org.apache.felix.ipojo.handlers.event">
+        <component className="...DataPublisher">
+    		<ev:publisher
+    			name="myPublisher"
+    			field="m_publisher"
+    			topics="myTopic"
+    			data-key="my.data"/>
+    	</component>
+    	<instance component="...DataPublisher"/>
+    </ipojo>
+
+Then you can use the *sendData* method of your configured publisher.
+
+    import org.apache.felix.ipojo.handlers.event.publisher.Publisher;
+    //...
+    public class DataPublisher ... {
+        private Publisher m_publisher;
+    
+        public void doSomething() {
+          // MyFavoriteType extends MyFavoriteInterface
+          MyFavoriteType data = new MyFavoriteType(...);
+          //...
+          // Send a data event
+          m_publisher.sendData(data);
+        }
+    }
+
+The second step is to configure an event subscriber to receive such events. The *data-key* attribute's  value of the subscriber must be the same than the publisher's one. The *data-type* describes the type of received data events, and thus, must be compatible with the sent object's type (i.e., super-class or inherited interface). Then you can finally receive the sent object in the callback method. The parameter type of the callback must be the same than the data-type attribute value.
+
+    <ipojo
+       xmlns:ev="org.apache.felix.ipojo.handlers.event">
+    	<component className="...DataEventSubscriber">
+    		<ev:subscriber
+    			name="mySubscriber"
+    			callback="handleData"
+    			topics="myTopic"
+    			data-key="my.data"
+    			data-type="my.package.MyFavoriteInterface"/>
+    	</component>
+    	<instance component="...DataEventSubscriber"/>
+    </ipojo>
+
+
+    import my.package.MyFavoriteInterface;
+    //...
+    public class DataEventSubscriber ... {
+      public void handleData(MyFavoriteInterface o) {
+         // Object received
+         //...
+       }
+    }
+
+
+Annotations use a different set of attributes:
+* data-key is replaced by `dataKey`
+* data-type is replaced by `dataType`
+
+### Note on synchronous event sending
+
+By default, events are sent using asynchronous sending (a.k.a.*post* in OSGi EventAdmin). You can use synchronous sending by defining the *synchronous* attribute of your publisher to true.
+
+The behavior of synchronous event sending is particular when you specify several topics in the publisher description. The event is synchronously sent to each topic, one by one. So when you return from this function, you can be sure that the event has been delivered to each topic.
+
+### Publisher instance information
+
+All events sent by a publisher contains the name of the component instance that sent them. Its enables to filter received events depending the sender instance. The instance name is accessible in the event dictionary by the key *publisher.instance.name*. Despite it goes against MOM principles, this property is useful to trace events and especially event sources.
+
+
+### Configuring the handler with annotations
+
+It is possible to configure the handler with a simple annotations available in the annotation pack ('annotation' project in the iPOJO trunk). Here is an example of usage:
+{code:java}
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.handlers.event.Subscriber;
+import org.apache.felix.ipojo.handlers.event.Publishes
+import org.apache.felix.ipojo.handlers.event.Publisher;
+import org.osgi.service.event.Event;
+
+
+@Component
+public class PubSub {
+    @Publishes(name="p1", synchronous=true)
+    Publisher publisher1;
+    
+    @Publishes(name="p2", synchronous=false, topics="foo,bar", data_key="data")
+    Publisher publisher2;
+    
+    @Publishes(name="p3", synchronous=true, topics="bar")
+    Publisher publisher3;
+    
+    @Subscriber(name="s1", data_key="data")
+    public void receive1(Object foo) {
+        // Process event
+    }
+    
+    @Subscriber(name="s2", topics="foo,bar", filter="(foo=true)")
+    public void receive2(Event foo) {
+        // Process event
+    }
+    
+    @Subscriber(name="s3", topics="foo", data*key="data", data*type="java.lang.String")
+    public void receive3(String foo) {
+        // Process event
+    }
+}
+
+    \\
+    {include:apache-felix-ipojo-footer}
\ No newline at end of file

Added: felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/extender-pattern-handler.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/extender-pattern-handler.mdtext?rev=1421893&view=auto
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/extender-pattern-handler.mdtext (added)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/extender-pattern-handler.mdtext Fri Dec 14 14:29:22 2012
@@ -0,0 +1,146 @@
+Title: Extender Pattern Handler
+
+{include:apache-felix-ipojo-header}
+
+<div class="content">
+
+
+#  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 entities:*
+* *The extender (also called host)* 
+* *The extensions*
+
+{div:class=toc}
+[TOC]
+{div}
+
+## The Extender pattern
+
+This architecture-style is based on two different roles:
+* The extender 
+* The extension
+
+!extender.png!
+
+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.
+You can also use annotations:
+
+    @Component
+    @Extender(
+    	onArrival="onBundleArrival",
+    	onDeparture="onBundleDeparture",
+    	extension="My-Extension")
+    public class MyExtender {
+    
+    	@Validate
+    	public void starting() {
+    	  // ...
+    	}
+    	
+    	@Invalidate
+    	public void stopping {
+    	  // ...
+    	}
+    
+    	void onBundleArrival(Bundle bundle, String header) {
+    	         // Do something
+    	}
+    
+    	void onBundleDeparture(Bundle bundle) {
+    	        // Do something
+    	}
+    }
+
+
+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
+
+
+
+<div class="box">
+	<div class="box-yellow-header">
+	<div class="box-yellow-title">
+		<img src="http://people.apache.org/~clement/ipojo/site/warning.gif"> <b>Called despite being invalid</b>
+	</div>
+	</div>
+	<div class="box-yellow-content">
+		The implementation will be notified of arrivals and departures despite the instance is invalid. Indeed, the implementation must release all objects created from another bundle as soon it leaves.
+	</div>
+	<div class="box-yellow-footer"></div>
+</div>
+
+
+## Download
+The handler is available on the [download]({{ refs.download.path }}) page.
+Sources are available on the Felix trunk at the following location: [http://svn.apache.org/repos/asf/felix/trunk/ipojo/handler/extender/](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:
+{code:java}
+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.
+    
+    
+    h2. A more realistic example
+    The Junit4OSGi framework, available [here|https://svn.apache.org/repos/asf/felix/trunk/ipojo/examples/junit4osgi] , 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.
+    \\
+    \\
+    {include:apache-felix-ipojo-footer}
\ No newline at end of file

Added: felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/ipojo-jmx-handler.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/ipojo-jmx-handler.mdtext?rev=1421893&view=auto
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/ipojo-jmx-handler.mdtext (added)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/ipojo-jmx-handler.mdtext Fri Dec 14 14:29:22 2012
@@ -0,0 +1,235 @@
+Title: iPOJO JMX Handler
+
+{include:apache-felix-ipojo-header}
+
+<div class="content">
+
+# iPOJO JMX Handler
+
+*This handler provides JMX management of component instance. It could be useful to manage instance remotely. As the handler exposes MBeans, you must have a MBean server running on your platform (as the platform MBean server or the MOSGi MBean Server).*
+
+{div:class=toc}
+[TOC]
+{div}
+
+## Features
+
+The handler allows to:
+* Expose attributes accessible via JMX (with right management).
+* Expose methods to be called through JMX.
+* Get notifications when attributes are modified .
+
+## Prerequisites
+
+To be functional this handler must register on an MBean Server,thus you obviously need it. Several servers are currently supported : the standard platform MBean server (included in the JDK), MOSGi (provided with Felix), ...
+To use MOSGi, you have to deploy at least the following three bundles of MOSGi:
+* org.apache.felix.mosgi.jmx.agent
+* org.apache.felix.mosgi.jmx.registry
+* org.apache.felix.mosgi.jmx.rmiconnector
+
+You can find MOSGi documentation on [http://cwiki.apache.org/FELIX/mosgi-managed-osgi-framework.html](http://cwiki.apache.org/FELIX/mosgi-managed-osgi-framework.html)
+
+## Download
+
+The JMX handler is available in the Felix trunk in the iPOJO project. See the [Download]({{ refs.download.path }}) page to download and compile these sources.
+
+## How to use it
+
+The handler needs to be added in the metadata.xml, you just add a namespace (e.g., jmx) :
+
+    <ipojo xmlns:jmx="org.apache.felix.ipojo.handlers.jmx">
+    	...
+    </ipojo>
+
+So, you could now expose in JMX properties and methods of your component. They are surrounded by the <jmx:config>
+tag.
+
+    <jmx:config>
+        <jmx:property name="message" field="m_msg" rights="w" notification="true"/>
+        <jmx:method name="doSomethingBad"/>
+        <jmx:method name="doSomethingGood"/>
+    </jmx:config>
+
+<div class="info" markdown="1">
+**Serialization**
+Be careful that the argument and return type of methods must be serializable. In case of several methods have the same name, each of them will be exposed.
+</div>
+
+## JMX Handler options
+
+Here you can find all configuration options of the JMX handler. There are two kinds of manageable elements : properties and methods. First is described the global configuration of the handler. Then elements can be configured, using several attributes, as described below.
+
+## Global handler attributes
+{div:class=borderedTable}
+|Attribute name | Required | Description|
+|--|--|--|
+|objectName|NO|The complete object name of the managed component. The syntax of this attribute must be compliant with the ObjectName syntax, detailed in the JMX specification.
+If neither domain nor name attributes are specified, the default value  is determined by the package, the type and the instance name of the component. This attribute overrides the domain and name attributes.
+*Example:* "my.domain:type=myType,name=myName"|
+|domain|NO|The domain of the managed object (i.e., the left part of the object name). This attribute must be compliant with the domain syntax, as described in the JMX specification.
+*Example:* "my.domain"|
+|name|NO|The name property of the managed object. The value of this attribute must comply with the ObjectName value syntax, as described in the JMX specification.
+|usesMOSGi|NO|Determines if the component must be register on the MOSGi MBean server or not.
+|preRegister 
+postRegister 
+preDeregister
+postDeregister|NO|These attributes allow to specify methods to carry out operations before and after being registered or unregistered from the MBean server.|
+{div}
+		
+## Properties attributes
+{div:class=borderedTable}
+|Attribute name|Required|Description|
+|--|--|--|
+|field|YES|The name of the component's field to expose.|
+|name|NO|The name of the property as it will appear in JMX. If unspecified, the default value is the name of the exposed field.|
+|rights|NO|Specify the access permission of the exposed field. The accepted values are : 
+* "r" : read-only access, the default value.
+* "w" : read and write access.|
+|notification|NO|Enable or disable attribute change notification sending for this property. If set to "true", a notification is sent each time the value of the field changes.|
+{div}
+## Methods attributes
+{div:class=borderedTable}
+|Attribute name|Required|Description|
+|--|--|--|
+|name|YES|The name of the method to expose. If multiple methods have the same name, all of them are exposed.|
+|description|NO|The description of the exposed method, as it will appear in JMX.|
+{div}
+
+## Examples
+
+In this part, we will give you a complete example of a component managed with JMX, using the JConsole provided by the SUN JDK.
+
+### Exposing Attributes
+
+In first time we create a simple component named MyComponent. We have add two fields named m*level (int) and m*message (String).
+
+    public class
+    MyComponent ... {
+    	// Exposed attributes
+    	private String m_message;
+    	private int m_level;
+    }
+
+We expose now the attributes in the jmx:config
+tag in the metadata :
+
+    <?xml version="1.0" encoding="UTF-8"?>
+    <iPOJO xmlns:jmx="org.apache.felix.ipojo.handlers.jmx">
+        <component className="...MyComponent"
+          architecture="true"
+          immediate="true">
+    
+          <provides/>
+          <jmx:config>
+    	<!-- Exposed properties -->
+    	<jmx:property field="m_level"
+              name="The level"
+              rights="r"/>
+    	<jmx:property field="m_message"
+              name="The message"
+              rights="w"/>
+          </jmx:config>
+        </component>
+        <instance
+          component="...MyComponent"/>
+    </iPOJO>
+
+Now, we could get and write the properties in the JConsole :
+!JMXHandler_1.png!
+
+### Exposing Methods
+
+We could now add methods in the initial class :
+
+    /**
+    Do something good
+    */
+    public void doSomethingGood() {
+    		...
+    }
+    
+    /**
+    Do something bad
+    */
+    public void doSomethingBad() {
+    		...
+    }
+    
+    /**
+    Do nothing
+    */
+    public void doNothing() {
+    		...
+    }
+
+We add corresponding tags in the metadata to expose these methods:
+
+    <!-- Exposed methods -->
+    <jmx:method name="doSomethingGood"
+          description="Do something good."/>
+    <jmx:method name="doSomethingBad"
+          description="Do something bad."/>
+    <jmx:method name="doNothing"
+          description="Do absolutely nothing."/>
+
+Now the three methods are exposed in the operations tab of the JConsole. We can invoked these methods :
+
+!JMXHandler_2.png!
+
+### Attribute Notifications:
+
+You could subscribe to attribute notification by adding the notification attribute in property tag. In our example if we want to be notified when m_level is modified, we change the property line in the metatada like this:
+
+    <jmx:property field="m_level"
+          name="The level"
+          rights="r"
+          notification="true"/>
+
+So now if we change the string through JConsole (or in the VisualVM) or if the POJO is modified in other way, a notification will be sent to every listener. For example, we subscribe in the notification tab, and we get notification when the message changes :
+
+!JMXHandler_3.png!
+
+## Configuring the handler with annotations
+
+It is possible to configure the handler with simple annotations available with iPOJO annotations. Here is an example of usage:
+{code:java}
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.handlers.jmx.Config;
+import org.apache.felix.ipojo.handlers.jmx.Method;
+import org.apache.felix.ipojo.handlers.jmx.Property;
+
+@Component
+@Config(domain="my-domain", usesMOSGi=false)
+public class JMXSimple {
+
+    @Property(name="prop", notification=true, rights="w") // Field published in the MBean
+    String m_foo;
+    
+    @Method(description="set the foo prop") // Method published in the MBean
+    public void setFoo(String mes) {
+        System.out.println("Set foo to " + mes);
+        m_foo = mes;
+    }
+    
+    @Method(description="get the foo prop") // Method published in the MBean
+    public String getFoo() {
+        return m_foo;
+    }
+}
+
+    The {{@org.apache.felix.ipojo.handlers.jmx.Config}} ({{@Config}} if the package it correctly imported) annotation is a type annotation (so placed on the {{class}} element. This annotation indicates that the instance will be exposed as an MBean. This annotation supports:
+    * usesMOSGi: set to {{true}} to use MOSGi. Otherwise, the MBean will be exposed in the MBean Platform Server (default: {{false}}).
+    * objectname: set the MBean objectname. The objectname must follow JMX specification. (default: {{package-name:factory-name:instance-name}})
+    * domain: set the MBean domain. (default: {{package-name}})
+    * name: set the MBean name. (default: {{instance-name}}).
+    
+    The {{@org.apache.felix.ipojo.handlers.jmx.Property}} ({{@Property}}) annotation is a field annotation indicating that the field is exposed in the MBean. The supported attributes are:
+    * name: set the property name
+    * rights: set the access permission. Possible values are {{r}} (read only) and {{w}} (read and write). By default, properties are in read-only mode.
+    * notification: enables notification on this property. By default notifications are disabled.
+    
+    The {{@org.apache.felix.ipojo.handlers.jmx.Method}} ({{@Method}}) annotation is a method annotation indicating that the method is exposed in the MBean. Only one attribute can be customized:
+    * description: set the method description.
+    \\
+    \\
+    {include:apache-felix-ipojo-footer}
\ No newline at end of file

Added: felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/lifecycle-callback-handler.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/lifecycle-callback-handler.mdtext?rev=1421893&view=auto
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/lifecycle-callback-handler.mdtext (added)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/lifecycle-callback-handler.mdtext Fri Dec 14 14:29:22 2012
@@ -0,0 +1,146 @@
+Title: Lifecycle Callback Handler
+
+{include:apache-felix-ipojo-header}
+
+<div class="content">
+
+# Lifecycle callbacks
+
+*It is often necessary to create a POJO object as soon the instance becomes valid (i.e. required services are available). It is also often needed to be able to stop it nicely. This pages presents the iPOJO capabilities to achieve such actions. iPOJO allows you to invoke methods (callbacks) on the POJO object when instance's state changed. For example, it allows invoking a `start` method when the instance becomes valid and a `stop` method when the instance becomes invalid. It allows the creation of `immediate` component. This page presents how to use this handler.*
+
+{div:class=toc}
+[TOC]
+{div}
+
+## Instance Lifecycle
+
+iPOJO instances have a very simple lifecycle. This lifecycle contains two states: `INVALID` and `VALID`. Once an instance is created, this instance can only be valid if all its plugged handlers are valid. In the most basic case it means all required services are available. For example, an instance requiring a service (and so using the dependency handler) cannot be valid if the required service is unavailable. 
+
+An instance starts and stops in the invalid state.
+
+!lifecycle.png|width=50%!
+
+## Lifecycle callback
+
+This handler supports two kinds of callback. The INVALID=>VALID callback are invoked when the instance becomes valid (at starting or when an event allows the instance to become valid). The VALID=>INVALID callback are invoked when the instance becomes invalid (at stopping or when an event invalids the instance).
+
+!callback.png!
+
+## An example
+
+Let's take an example. The following class requires a FooService and has two lifecycle callbacks: start and stop.
+
+    @Component
+    @Instantiate
+    public class Foo {
+                  @Requires
+                  FooService fs;
+    
+                  @Validate
+                  private void start() {
+                           // Starting method
+                           //...
+                           fs.foo();
+                           //...
+                    }
+    
+                    @Invalidate
+                    protected void stop() {
+                            // Stopping method
+                			if(fs!=null) { fs.foo(); }
+                    }
+    }
+
+You can also remove the annotations to use the XML format:
+
+    <component className="...Foo">
+           <requires field="fs"/>
+           <callback transition="validate" method="start"/>
+           <callback transition="invalidate" method="stop"/>
+    </component>
+    <instance component="...Foo"/>
+
+When an instance of this component type is created, the start method is called as soon as the `Foo` Service (service requirement) becomes available. If the `Foo` Service is no more available or when the instance is stopped, the stop method is called.
+
+The invoked methods have no argument, but could be private, protected or public. Public methods can be in parent classes too. Moreover, the `INVALID=>VALID` (validate) method can use service dependencies (the instance becomes valid means that all required services are available); however, in the stop method (invalidate) it is possible that one of these dependency can be `null`. Indeed, the departure of a service can be the cause of the instance invalidation.
+
+## Managing threads
+
+One usage of lifecycle callback is when the instance needs to create threads. Indeed, the thread can be created in the validate callback, and stopped in the invalidate method. The next class shows an example of a class handling a thread by using lifecycle callbacks.
+
+    @Component
+    @Instantiate
+    public class HelloRequesterImpl implements Runnable {
+    
+        final static int DELAY=10000;
+    
+        @Requires
+        HelloService[] m_hello;&nbsp; // Service Dependency
+    
+        boolean end;
+    
+        public void run() {
+          while (!end) {
+            try {
+            synchronized (this) {
+              for(int i = 0; i < m_hello.length; i++) {
+                System.out.println(m_hello[i].sayHello("Clement"));
+              }
+            }
+            Thread.sleep(DELAY);
+            } catch (InterruptedException ie) {
+                 /* will recheck quit */
+            }
+        }
+       }
+    
+        @Validate
+        public void starting() {
+          Thread T = new Thread(this);
+          end = false;
+          T.start();
+        }
+    
+        @Invalidate
+        public void stopping() { end = true; }
+
+
+## Invalidate callbacks and services
+The invalidate callback has to be developed defensively. Indeed, inside this callback, it might be possible that a service is no more there (the departure of this service has thrown the instance invalidation, which calls the callback). So, you must check that the service is not `null` before using it:
+
+    @Invalidate
+    public void stop() {
+      if (myservice != null) {
+        // you can use the service
+      }
+      // ...
+    }
+
+Thanks to the iPOJO synchronization model, you can be sure that if the service is available, it will be there until the end of the method.
+
+## Immediate component
+
+An instance of an `immediate` component type is instantiated as soon it becomes valid. It means that, when the instance becomes valid, the constructor of the implementation class is called. This can replace the validate callback. However, it stills a difference between the immediate and the validate callback. The constructor is call only once time. The validate callback is re-called each time the instance becomes valid. Components that do not provide services are automatically set as immediate.
+
+!constructor.png!
+
+To set a component as immediate you must add the `immediate` attribute to `component`:
+
+    @Component(immediate=true)
+    @Instantiate
+    public class MyComponent implements MyService {
+       // ...
+    }
+
+
+However as there is no 'destructor' in Java, the invalidate callback is necessary if some actions are needed when stopping.
+
+
+## Callback on several objects
+
+If you instance has created several objects (called the implementation class constructor several times), the callback is called on each object in the creation order.
+  
+  
+  
+  
+{include:apache-felix-ipojo-footer}
\ No newline at end of file

Added: felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/providing-osgi-services.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/providing-osgi-services.mdtext?rev=1421893&view=auto
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/providing-osgi-services.mdtext (added)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/providing-osgi-services.mdtext Fri Dec 14 14:29:22 2012
@@ -0,0 +1,392 @@
+Title: Providing OSGi services
+
+{include:apache-felix-ipojo-header}
+
+<div class="content">
+
+# Providing OSGi services
+
+*This pages explains how to publish OSGi services with iPOJO. It presents:*
+* *service publication*
+* *service properties publication and management*
+* *service object creation and creation strategies*
+* *service un-registration*
+* *configuration property propagation*
+* *the management of the exposition from the implementation class*
+
+{div:class=toc}
+[TOC]
+{div}
+
+## A simple example
+
+The following code snippet shows a simple class implementing the `FooService` interface:
+
+    @Component
+    @Provides
+    public class FooProviderType1 implements FooService {
+                private String m_foo = "foo";
+    
+                public void foo() {
+                            System.out.println("foo  " + m_foo);
+                }
+    
+    }
+
+To provide a service, the implementation class *MUST* implement the service interface. 
+
+In XML, to provide the service, the component type needs to contain the `<provides/>` element:
+
+    <component className="...FooProviderType1">
+            <provides/>
+    </component>
+
+!ps-foo.png!
+
+The `<provides/>` or `@Provides` suffice to declare that each instance of this type will provide the FooService (for more info about instances see [FELIX:How-to use iPOJO factories]({{ refs.felix-how-to-use-ipojo-factories.path }})). The provided specifications can be discovered by analyzing the implementation class. By default, all implemented interface are published in the same service registration. iPOJO looks down the entire inheritance tree.
+
+## Service Publication
+
+The provided service handler manages service publication. For each declared `<provides/>`, the handler registers a service. Since the `@Provides` annotation can be used only once, only one service is registered that provides all interfaces. The service is published as long as the instance is valid. If the instance becomes invalid, the service is removed from the service registry.
+
+By default, it publishes all interfaces implemented by the implementation class of the component class. It collects all super-interfaces (interfaces implemented by implemented interfaces and by the super class). However, it is possible to explicitly declare which service specifications are published with the `specifications` attribute, such as:
+
+
+    @Component
+    @Provides(specifications={FooService.class})
+    public class FooProviderType1 implements FooService, Runnable {
+        // ...
+    }
+
+
+<div class="info" markdown="1">
+**Change in the 1.2.0**
+In the 1.0.0 version and before, the `specifications` attribute was named `interface`.
+</div>
+
+<div class="info" markdown="1">
+**Specification checking**
+If you use the `specifications` attribute, the handler checks that all declared interfaces are really implemented by the implementation class. If an interface is not implemented, the handler logs a warning.
+</div>
+
+<div class="info" markdown="1">
+**No service**
+If the implementation class does not implement any interface, you cannot provide a service. In this case, the handler throws an error.
+</div>
+
+## Service Properties
+
+You can also attach properties to a service registration. Service properties are attached to published service and allow consumer filtering/selecting providers. A property can be attached to a field (contained in the component implementation class), and so can be handle dynamically.
+
+Let's take a new example very closed of the last one:
+
+    @Component
+    @Provides
+    public class FooProviderType1 implements FooService {
+    
+        @ServiceProperty(name="foo", value="Foo")
+    	private String m_foo;
+    
+    	public void foo() {
+    		System.out.println("foo  " + m_foo);
+            m_foo = "bar";
+    	}
+    }
+
+Using XML, it gives:
+
+    <component classname="...FooProviderType1">
+                <provides>
+                            <property name="foo" field="m_foo" value="Foo"/>
+                </provides>
+    </component>
+
+
+The declared property is attached to the `m*foo` field. This property is published with the name `foo`. This property has a default value "Foo". This value will be injected into the `m*foo` field, when this field asks for a value. A property with a field attribute does not need to declare a type (the type can be discovered by analyzing the implementation class).
+
+The implementation class set a new value to the `m_foo` field in the code. When this action occurs, the service publication is updated. If a published property value becomes `null`, the property is unpublished since it has a new value.
+
+
+You can also publish 'static' properties (not attached to a field):
+
+    @Component
+    @Provides(properties= {
+    			@StaticServiceProperty(name="static", type="java.lang.String", value="this is a static property")
+    	})
+    public class FooProviderType1 implements FooService {
+    
+        @ServiceProperty(name="foo", value="Foo")
+    	private String m_foo;
+    
+    	public void foo() {
+    		System.out.println("foo  " + m_foo);
+            m_foo = "bar";
+    	}
+    }
+
+
+The second property (`Static`) is published as a static property. This property is not attached to a field, so, we need to declare the property type. All primitive types or objects can be used has property type (for object, the qualified name of the class is used as java.lang.String).
+
+In XML, this can also be done:
+
+    <component classname="...FooProviderType1">
+                <provides>
+                            <property name="foo" field="m_foo" value="Foo"/>
+                            <property name="static" type="java.lang.String" value="this is a static property"/>
+                </provides>
+    </component>
+
+
+Properties may have a default value (set using the `value` attribute). This value will be used as initial value. The value can be given in the instance configuration. The default value will be overridden in this case:
+
+    <instance component="...FooProviderType1">
+       <property name="foo" value="My New Foo Value"/>
+       <property name="static" value="My Value For Static"/>
+    </instance>
+
+
+Properties can also be 'mandatory'. Mandatories properties must receive a value from the instance configuration. If the instance configuration *forgets* a mandatory properties, the configuration is rejected. Mandatory attribute let you be sure to receive the complete set of initialization values:
+
+    @Component
+    @Provides
+    public class MyComponent implements MyService {
+    
+        @ServiceProperty(name="username", mandatory=true)
+        private String m_username;
+    
+        @Property(name="password", mandatory=true)
+        private String m_password;
+    
+        //...
+    }
+
+
+For the previous components:
+* `(name=myname, password=****)` is a valid configuration
+* `(password=****)` is an invalid configuration that will be rejected by iPOJO
+
+
+## Advanced features
+
+### Service Serving & Object Creation
+
+When a consumer requires the published service, the handler sends an object (from the component class) of the implementation class. By default, it is always the same POJO object. If no objects already exists, an instance is created.
+
+However, the handler supports the OSGi *Service Factory*. In this case, for each requester bundle, the handler sends a new object. To activate this policy, add the `strategy` attribute in the `provides` element:
+
+
+    @Component
+    @Provides(strategy="SERVICE")
+    public class MyComponent implements MyService {
+        //...
+    }
+
+or:
+
+    <provides strategy="SERVICE"/>
+
+
+Other strategies are available:
+ * `strategy="instance"` allows creating one service object per iPOJO instance using the service
+ * it is possible to create your own creation strategy by extending the `org.apache.felix.ipojo.handlers.providedservice.CreationStrategy` class and by indicating the qualified class name in the `strategy` attribute:
+
+    @Component
+    @Provides(strategy="org.acme.foo.MyCreationStrategy")
+    public class MyComponent implements MyService {
+        //...
+    }
+
+
+### Providing Several Services (XML only)
+In XML, you can declare several `provides` inside the same component. All those provided services will be managed individually, so will be published using several publication (i.e. `org.osgi.frameowrk.ServiceRegistration`). This case is useful when service properties are different for the different services.
+
+    <component classname="...FooProviderType1">
+                    <provides specifications="...Foo"/>
+                    <provides specifications="...Bar">
+                                   <property name="foo" value="baz"/>
+                    </provides>
+    </component>
+
+!ps-foobar2.png!
+
+### Service Property Propagation
+
+The configuration handler has the possibility to propagate received properties to service publication. So, when the propagation is activated (on the `properties` element or on the `@Component` annotation), all properties received by the configuration handler will be propagated to all published services. If some properties are mapped on methods, these methods are invoked with the new value in argument.
+
+!ps-propagation.png!
+
+If an instance configuration contains properties starting with `service.`, they are automatically propagated. In the following example, the `service.pid` is automatically propagated.
+
+    <instance component="...">
+        <property name="service.pid" value="my.pid"/>
+    </instance>
+
+
+### Instance reconfiguration
+
+iPOJO supports instance reconfiguration. When an instance is dynamically reconfigured and if the instance published service properties, the values are updated with the new configuration. For example, let's take the following component.
+
+{code:java}
+@Component
+@Instantiate
+@Provides
+public class MyComponent implements MyService {
+
+    @ServiceProperty(name="prop", value="initial")
+    private String myProp;
+
+    //...
+    
+}
+
+    
+    The previous code also declares an instance (created without any configuration). This instance registers {{MyService}} with the service property {{prop}}={{initial}}. If this instance is reconfigured using a configuration like: {{\{prop="my value"\}}}, the published properties will be updated with the new value, so {{prop}}={{my value}}.
+    
+    h3. Publishing an abstract or concrete class as a Service
+    
+    It is also possible to expose an abstract or concrete class as a service. To to this, just specify the published class in the {{specifications}} attribute:
+
+@Component
+@Provides(specifications=MyComponent.class)
+public class MyComponent {
+    // ...
+}
+
+    or in XML:
+    {code:xml}
+    <component classname="...FooProviderType1">
+                    <provides specifications="...AbstractFoo"/>
+    </component>
+    <component classname="...FooBarProviderType1">
+                    <provides specifications="[...AbstractFoo, ...Bar]"/>
+    </component>
+
+As illustrated with the example using annotation, the component can also publish itself as a service. However, such practice is not recommended.
+
+### Controlling the service exposition from the implementation class
+
+To control the exposition of the published service, you can use a `service controller`. A service controller is a boolean field of the component class. The injected boolean field allows the code to impact the service publication. Setting the field to `false` unregisters the service from the service registry. Setting it back to `true` re-publishes the service.
+
+{code:java}
+@Component
+@Provides
+public class ControllerCheckService implements FooService, CheckService {
+    
+    @ServiceController
+    private boolean controller; // Service Controller
+
+    public boolean foo() {
+        return controller;
+    }
+
+    public boolean check() {
+        System.out.println("Before : " + controller);
+        controller = ! controller; // Change the publication
+        System.out.println("After : " + controller);
+        return controller;
+    }
+
+}
+
+    
+    Using XML, the previous component description is:
+    {code:xml}
+      <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"
+        name="PS-Controller-1-default">
+        <provides>
+          <controller field="controller"/>
+        </provides>
+      </component>
+
+
+The `controller` may have a value attribute setting the initial value. Setting this value to `false` disables the initial service registration:
+
+    @Component
+    @Provides
+    public class ControllerCheckService implements FooService, CheckService {
+        
+        @ServiceController(value=false)
+        private boolean controller; // Service Controller
+    
+        public boolean foo() {
+            return controller;
+        }
+    
+        public boolean check() {
+            System.out.println("Before : " + controller);
+            controller = ! controller; // Change the publication
+            System.out.println("After : " + controller);
+            return controller;
+        }
+    
+    }
+
+
+If several interfaces are exposed, the controller may have a `specification` attribute indicating the impacted service:
+
+    @Component
+    @Provides
+    public class ControllerCheckService implements FooService, CheckService {
+        
+        @ServiceController(value=false, specification=FooService.class)
+        private boolean controller; // Service Controller
+    
+        public boolean foo() {
+            return controller;
+        }
+    
+        public boolean check() {
+            System.out.println("Before : " + controller);
+            controller = ! controller; // Change the publication
+            System.out.println("After : " + controller);
+            return controller;
+        }
+    
+    }
+
+
+In XML, each `provides` can have one `controller` element.
+
+      <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"
+        name="PS-Controller-1-false">
+        <provides>
+          <controller field="controller" value="false"/>
+        </provides>
+      </component>
+
+
+### Being notified of the service registration and unregistration
+You can also be notified when the service is published and unpublished. This is done by specifying the two callbacks in the `<provides/>` element:
+
+    <component
+         classname="org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"
+         name="PS-Callbacks-both-1">
+        <provides
+    	specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService"
+    	post-unregistration="unregistered" post-registration="registered"/>
+        <provides
+    	specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService"
+    	post-unregistration="unregistered" post-registration="registered"/>
+    </component>
+
+Or by using the @PostRegistration and @PostUnregistration annotations:
+{code:java}
+	@PostRegistration
+	public void registered(ServiceReference ref) {
+		System.out.println("Registered");
+	}
+
+        @PostUnregistration
+	public void unregistered(ServiceReference ref) {
+		System.out.println("Unregistered");
+	}
+
+    
+    * The {{post-registration}} callback is called after the service publication
+    * The {{post-unregistration}} callback is called after the service unpublication
+    
+    Those callback methods must have the following signature: {{public void name(ServiceReference ref)}}. So they receive the published / unpublished service reference. The callbacks are called in the *same thread* as the publication / unpublication itself. 
+    
+    \\
+    \\
+    {include:apache-felix-ipojo-footer}
\ No newline at end of file

Added: felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/service-requirement-handler.mdtext
URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/service-requirement-handler.mdtext?rev=1421893&view=auto
==============================================================================
--- felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/service-requirement-handler.mdtext (added)
+++ felix/site/trunk/content/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/describing-components/service-requirement-handler.mdtext Fri Dec 14 14:29:22 2012
@@ -0,0 +1,626 @@
+Title: Service Requirement Handler
+
+{include:apache-felix-ipojo-header}
+
+<div class="content">
+
+
+# Service Dependency Management
+
+*One of the main iPOJO feature is the service injection. So, a component can consume a service without managing the service discovery, tracking and binding. iPOJO manages all these interactions and injects required service into the component. This page explains how to use services.*
+
+{div:class=toc}
+[TOC]
+{div}
+
+## Service Requirement
+
+### What's a service requirement?
+
+A requirement represents a required service. Therefore, it manages the service lookup and the service binding. When an instance requires a service, the handler injects directly a service object inside a field, or invokes a method when a consistent service appears (or disappears). Service requirements can be:
+* Simple / Aggregate : the component can require      one or several service providers
+* Mandatory / Optional : a component can declare an      optional dependency
+* Filtered : a component can filter available      providers
+* Dynamic / Static / Dynamic-Priority : the      component can specify the binding policy
+* Specific : the dependency targets a specific service provider
+* Proxy : by default, iPOJO injects a smart proxy, but it can also be a dynamic proxy or the direct references
+
+### Dynamism & Instance Lifecycle
+
+In OSGi™, services can appear and disappear dynamically. This implies dependencies can target a provider which can appear or disappear dynamically. So, dependencies need to manage this dynamism by tracking every time available services. At any moment, a dependency can be unresolved (i.e. no more provider can fulfill the requirement). In the case of a mandatory requirement, the instance becomes invalid (an invalid instance is no more accessible externally, for example provided services are unpublished). If a service, resolving the unfilled dependency appears, the instance becomes valid. In consequence, dependencies affect directly the instance state, and must manage correctly OSGi dynamism to allow a complete unloading when a service goes away. As soon a mandatory dependency cannot be fulfilled, the instance is invalidated.
+
+By default, dependencies are managed dynamically (as previously explained). However, iPOJO supports two other types of binding policies:
+* Static : if a bound service disappears, the instance is invalidated and cannot be revalidated (binding broken forever)
+* Dynamic-Priority: at each injection, the *best* provider is injected, or the providers array is sorted according to the OSGi Ranking policy or to a specified sorting algorithm.
+
+## Service Requirement Injection Mechanisms
+
+iPOJO support several types of injections:
+* Field injection: a field contains the service object. As soon as the field is used, a consistent service object is      injected. This injection type fully hides the dynamism
+
+    @Requires
+    private LogService log;
+
+* Method invocation: when a service appears, or disappears a method in the component is invoked. For each dependency, bind / unbind / modified methods are invoked to notify the component of the event.
+
+    @Bind
+    public void bindLogService(LogService log) { /*...*/ }
+    @Unbind
+    public void unbindLogService(LogService log) { /*...*/ }
+    @Modified
+    public void modifiedLogService(LogService log) { /*...*/ }
+
+* Constructor injection: services can also be injected as constructor parameter (only if proxies are enabled). *1.7.0-SNAPSHOT*
+
+    public MyComponent(@Requires LogService log) { /*...*/ }
+
+
+Moreover, the injections types can be mixed. A component can declare a requirement containing both a field and 'binding' methods.
+
+### Field injection
+
+Let's imagine a Hello service with one method 'getMessage' returning a "Hello Message". The following component implementation can use this service by attaching this service to a field and by using the field:
+{code:java}
+@Component
+@Instantiate
+public class HelloConsumer {
+    @Requires
+    private Hello m_hello;
+
+    public doSomething() {
+        System.out.println(m_hello.getMesage());
+    }
+}
+
+    You can also use XML to describe this component type:
+    {code:xml}
+    <component classname="...HelloConsumer">
+        <requires field="m_hello"/>
+        ...
+    </component>
+
+The metadata contains a 'requires' element (representing the service dependency) and specify a field used to inject the service. The implementation uses the field as a normal field without managing service interactions.
+
+### Method invocation
+
+The second injection mechanism uses methods in the implementation class. By this way, the dynamics can be managed directly by the developer. Each dependency can declare three methods:
+* A bind method called when a service appears
+* An unbind method called when a service disappears
+* A modified method called when a service is modified (the service properties changed, but the service still matches the requirement)
+
+Moreover, callbacks can be in the component super class (in this case methods must be public). These methods can have one of these four signatures:
+* Without any argument: the method is just a  notification (method())
+* With the service object : the object is the  implicated service object (method(Service svc))
+* With an OSGi service reference: the service  reference appearing or disappearing (method(ServiceReference ref))
+* With the service object and the OSGi service reference (method(Service svc, ServiceReference ref))
+* With the service object and the service properties inside a Map (method(Service svc, Map properties))
+* With the service object and the service properties inside a Dictionary (method(Service svc, Dictionary properties))
+
+The following component implementation shows an example of implementation using this mechanism:
+{code:java}
+@Component
+public class HelloConsumer {
+  private Hello m_hello;
+
+  @Bind
+  public void bindHello(Hello h) { m_hello = h; }
+  @Unbind
+  public void unbindHello() { m_hello = null; }
+  public doSomething() { System.out.println(m_hello.getMesage()); }
+}
+
+    The {{modified}} callback is not mandatory. The following XML metadata are describing the same component type:
+    {code:xml}
+    <component classname="...HelloConsumer">
+    <requires>
+        <callback type="bind" method="bindHello">
+        <callback type="unbind" method="unbindHello">
+    </requires>
+    ...
+    </component>
+
+Note, that the different callbacks can be have different signatures. By using this mechanism, you need to be sure to manage the dynamism correctly.
+([See note on type discovery]({{ refs.-discovery.path }}))
+
+Using the @Modified callback is also quite simple:
+{code:java}
+@Component
+public class HelloConsumer {
+  private Hello m_hello;
+
+  @Bind
+  public void bindHello(Hello h) { m_hello = h; }
+  @Unbind
+  public void unbindHello() { m_hello = null; }
+  @Modified
+  public void modifiedHello() { /* ... */ }
+  public doSomething() { System.out.println(m_hello.getMesage()); }
+
+}
+
+    
+    h3. Using constructor injection (*1.7.0-SNAPSHOT*)
+    Services can also be injected using constructor parameters:
+
+@Component
+public class MyComponent {
+    private LogService log;
+
+    public MyComponent(@Requires LogService log) {
+        this.log = log;
+    }
+}
+
+    
+    h3. Mixing injections types
+    
+    The different mechanisms can be used together. In this case, the field receives the value before the bind method invocation. Constructor parameters get their values during the constructor invocation. So, if the field is used in the method, the returned value will be up to date. The following component implementation uses this mechanism:
+    {code:java}
+    public class HelloConsumer {
+         @Requires(id="hello")
+         private Hello m_hello; // Injected Field
+    
+         @Bind(id="hello")
+         public void bindHello() { System.out.println("Hello appears"); }
+         @Unbind(id="hello")
+         public void unbindHello() { System.out.println("Hello disapears"); }
+    
+         public doSomething() { System.out.println(m_hello.getMesage()); }
+    }
+
+
+In XML, it results in:
+
+    <component classname="...HelloConsumer">
+        <requires  field="m_hello">
+            <callback type="bind" method="bindHello">
+            <callback type="unbind" method="unbindHello">
+        </requires>
+        ...
+    </component>
+
+
+The `id` attribute is used to determine which callbacks / fields go together. If ommitted, it is computed automaticcally:
+* for field it uses the field type.
+* for method starting with `bind` / `unbind` / `modified`, it extract the end of the method name (`bindFoo => Foo`)
+* for constructor parameter, it uses the parameter index
+
+So, it is strongly recommended to specify the id manually. 
+
+### Injection mechanisms & lazy object creation
+
+iPOJO creates objects only when required. When needed, iPOJO invokes the constructor of the implementation class. The implementation class can use field requirement because values are already injected and obviously constructor parameters. However, method dependencies are called *after* the constructor. If the service is available before the constructor call, the invocation of the bind methods is delayed until the a component class object is created.
+
+## Examples
+
+For all examples both annotations and XML forms are given. Just choose what you'd like to use.
+
+### Simple Requirement
+
+By default, a requirement is mandatory, non-filtered and simple (non-aggregate). The previous examples illustrate this kind of dependency. When services goes away and appears, the service substitution is hidden. Fields attached to simple requirement point always a consistent service object. For a simple dependency, the bind method is called once time when the service appears or just after the POJO constructor invocation is the service is available. When the service disappears the unbind method is called. The bind method is re-invoked as soon as another service provider is available. This invocation occurs immediately if another service provider if available. In this case, the instance is not invalidated.
+
+### Aggregate Requirement
+
+When a component requires several providers of the same service, it declares an aggregate dependency.
+
+#### Aggregate Dependency with field injection
+
+{code:java}
+@Component
+public class HelloConsumer {
+     @Requires
+     private Hello m_hellos[]({{ refs..path }}); // Array => Aggregate
+     public doSomething() {
+             for(int I = 0; I < m_hellos.length; i++) { 
+                 System.out.println(m_hellos[i]({{ refs.i.path }}).getMessage());
+             }
+       }
+}
+
+    
+    For this component, XML metadata could be:
+    {code:xml}
+    <component classname="...HelloConsumer">
+        <requires field="m_hellos"/>
+        ...
+    </component>
+
+
+To declare an aggregate field for field requirement, you only need to declare an array (instead of a scalar type). iPOJO will create and inject the service object array. iPOJO discover that the dependency is aggregate during the bytecode introspection.
+
+Array types cannot be 'proxied'. Moreover array dependencies cannot be injected as constructor parameter.
+
+<div class="info" markdown="1">
+**Synchronization**
+The synchronization is managed by iPOJO. As soon as you are 'touching' a dependency in a method, iPOJO ensure that you will keep these objects until the end of the method. Nested methods will share the same service object set.
+</div>
+
+#### Aggregate Dependency with field injection: list, vector, collection and set
+It is also possible to inject service objects inside fields of the type:
+* list
+* vector
+* collection
+* set
+
+{code:java}
+@Component
+public class HelloConsumer {
+     @Requires(specification="org.apache.felix.ipojo.example.Hello")
+     private List<Hello> m_hellos;
+     public doSomething() {
+             for(Hello h : m_hellos) { 
+                 System.out.println(h).getMessage());
+             }
+       }
+}
+
+    For this component, XML metadata could be:
+    {code:xml}
+    <component classname="...HelloConsumer">
+        <requires field="m_hellos" specification="org.apache.felix.ipojo.example.Hello"/>
+        ...
+    </component>
+
+
+In this case, just use the supported type that you want. iPOJO will automatically understand that it is an aggregate dependency, and will create the collection object containing service objects. However, you must specify the service specification. Indeed, generics types cannot be discovered at runtime reliably. 
+
+<div class="info" markdown="1">
+**Service specification discovery**
+The service specification (i.e. interface) cannot be discovered when using these types as the bytecode does not provide enough information. So, you have to indicate the required service interface (with the 'specification' attribute) in the requirement description.
+</div>
+
+<div class="info" markdown="1">
+**How iPOJO manage the synchronization for you**
+As in the previous case, the synchronization is managed by iPOJO. As soon as you are *touching* a dependency in a method, iPOJO ensure that you will keep these objects until the end of the method. Nested methods will share the same service object set.
+</div>
+
+#### Aggregate Dependency with callbacks
+
+{code:java}
+public class HelloConsumer {
+      private List m_hellos = new ArrayList();
+      @Bind(aggregate=true)
+      private void bindHello(Hello h) { m_hellos.add(h); }
+      @Unbind
+      private void unbindHello(Hello h) { m_hellos.remove(h); }
+      public synchronized doSomething() {
+                  for(Hello h : m_hellos) { 
+                    System.out.println(h.getMessage());
+                  }
+                }
+        }
+}
+
+    This dependency can also be described in XML as follow:
+    {code:xml}
+    <requires  aggregate="true">
+        <callback type="bind" method="bindHello">
+        <callback type="unbind" method="unbindHello">
+    </requires>
+
+In this case, iPOJO cannot detect if the dependency is aggregate or not. So, you need to add the '*aggregate*' attribute. The bindHello and unbindHello will be called each time a Hello service appears or disappears.
+
+<div class="info" markdown="1">
+**Synchronization**
+To avoid the list modification during the loop, you need synchronized the block. Indeed, as the field is not an iPOJO requirement, iPOJO will not manage the synchronization.
+</div>
+
+### Optional Requirement (Scalar)
+
+An optional requirement does not invalidate the instance despite no providers are available. Moreover, it is possible to inject a default service implementation when no *real* providers are available.
+
+#### Optional Requirement with field injection
+
+{code:java}
+@Component
+public class HelloConsumer {
+         @Requires(optional=true)
+         private Hello m_hello;
+
+         public doSomething() {  
+            System.out.println(m_hello.getMesage());  
+         }
+}
+
+    For this component, equivalent XML metadata could be:
+    {code:xml}
+    <component classname="...HelloConsumer">
+        <requires field="m_hello" optional="true"/>
+        ...
+    </component>
+
+To declare an optional requirement, you need to add the *'optional'* attribute. To avoid `null` pointer exception, iPOJO injects a `Nullable` object in the field when no service provider is available. The *nullable* object implements the service interface, but does nothing. Moreover, it is possible to set a *default-implementation* for the service. A default-implementation is a class implementing the service but used only when no others service providers are available. The default-implementation object will be injected instead of the *Nullable* objet. For further information [refer to the note about nullable object]({{ refs.-nullable.path }}).
+
+#### Optional Dependency with callbacks invocation
+
+{code:java}
+@Component
+public class HelloConsumer {
+     private Hello m_hello;
+
+     @Bind(optional=true)
+     public void bindHello(Hello h) { m_hello = h; }
+
+     @Unbind
+     public void unbindHello() { m_hello = null; }
+
+     public doSomething() { 
+          if(m_hello != null) { // Must be checked
+              System.out.println(m_hello.getMesage()); 
+          }
+    }
+}
+
+    For this component, XML metadata could be:
+    {code:xml}
+    <component classname="...HelloConsumer">
+    <requires optional="true">
+        <callback type="bind" method="bindHello">
+        <callback type="unbind" method="unbindHello">
+    </requires>
+    ...
+    </component>
+
+As for field requirement, the dependency metadata needs to contain the optional attribute. iPOJO invokes the method only when a 'real' service is available, so you need to test if `m_hello` is `null` before to use it.
+
+### Aggregate & Optional Requirement
+
+A dependency can be both aggregate and optional.
+
+#### Aggregate & Optional Dependency with field injection
+
+{code:java}
+@Component
+public class HelloConsumer {
+     @Requires(optional=true)
+     private Hello m_hellos[]({{ refs..path }});
+
+     public doSomething() {
+           for(Hello h : m_hellos) { 
+             System.out.println(h.getMessage());
+           }
+     }
+}
+
+    For this component, XML metadata could be:
+    {code:xml}
+    <component classname="...HelloConsumer">
+    <requires field="m_hellos" optional="true"/>
+    ...
+    </component>
+
+To declare an optional & aggregate field requirement you need to write the optional attribute in the dependency metadata and to point on a field array. If no service available, iPOJO injects an empty array.
+
+#### Aggregate & Optional Requirement with callbacks
+
+{code:java}
+@Compoent
+public class HelloConsumer {
+
+     private List m_hellos<Hello> = new ArrayList<Hello>();
+
+     @Bind(aggregate=true, optional=true)
+     private void bindHello(Hello h) { m_hellos.add(h); }
+
+     @Unbind
+     private void unbindHello(Hello h) { m_hellos.remove(h); }
+
+     public synchronized doSomething() {
+               for(Hello h : m_hellos) { 
+                  System.out.println(h.getMessage());
+               }
+     }
+}
+
+    For this component, XML metadata could be:
+    {code:xml}
+    <requires aggregate="true" optional="true">
+         <callback type="bind" method="bindHello">
+         <callback type="unbind" method="unbindHello">
+    </requires>
+
+In this case, you need to add the *'aggregate'*attribute and the *'optional'*attribute. The `bindHello` and `unbindHello` will be called each time a Hello service appears or disappears. These bind / unbind methods are not called when binding / unbinding a Nullable object (when both field and method are used).
+
+### Filtered Requirement
+
+A filtered dependency applies an LDAP filter on service provider. iPOJO reuses OSGi LDAP filter ability. The following metadata illustrates how to use filters:
+
+    @Requires(filter="(language=fr)")
+    private String DictionaryService dict;
+
+
+
+    <requires filter="(language=fr)" field="dict"/>
+
+
+To add a filter, just add a 'filter' attribute in your dependency containing the LDAP filter. iPOJO will select only provider matching with this filter.
+
+When using a filter, you can also use the `modified` callback invoked when a matching service is *modified* but still matches the filter:
+
+    @Component
+    public class MyComponent {
+    
+        @Bind(filter="(langage=en)")
+        public void bindHDictionary(DictionaryService svc) { ... }
+    
+        @Unbind
+        public void unbindDictionary() { ...}
+    
+        @Modified
+        public void modifiedDictionary() { ... }
+    
+    }
+
+
+Moreover, filters can be customized instance by instance. It is possible to specialize / change / add the filter of a component in the instance description. It is useful when you want to create different instances of the same component, with different filter. To achieve this customization, you have to identify your dependency with the 'id' attribute. Then, you can adapt the filter of the dependency in the instance description by using the property "requires.filters". In this property you can specify each dependency identified by its id and the new value of the filter.
+
+    <component 
+       className="org.apache.felix.ipojo.example.FilteredDependency">
+    	<requires field="m_foo" fiter="(foo.property=FOO)" id="id1">
+    		<callback type="bind" method="bind"/>
+    		<callback type="unbind" method="unbind"/>
+    	</requires>
+    </component>
+    
+    <instance name="FOO1" component="FOO"/>
+    
+    <instance name="FOO2" component="FOO">
+    	<property name="requires.filters">
+    		<property name="id1" value="(foo.property=BAR)"/>
+    	</property>
+    </instance>
+    
+    <instance name="FOO3" component="FOO">
+    	<property name="requires.filters">
+    		<property name="id1" value="(foo.property=BAZ)"/>
+    	</property>
+    </instance>
+
+The component type declares a service dependency with the 'id1' id. This dependency has no filter by default. The first instance is just an instance of the FOO component type and does not modify the dependency. The second one adds a filter to the declared dependency to target providers with foo.property = BAR. The last one adds another filter to the declared dependency. By using instance filter customization, it is possible to create complex applications where you avoid binding problems by filtering dependencies instance by instance.
+
+### Targeting a specific provider
+A service dependency can choose a specific provider. To achieve this, add a 'from' attribute in your requirement description such as in:
+
+    @Requires(from="MyHelloProvider")
+    private Hello m_hello;
+
+or in XML:
+
+    <requires from="MyHelloProvider" field="m_hello"/>
+
+iPOJO maps the `from` attribute to a specific filter : '|(instance.name=MyHelloProvider)(service.pid=MyHelloProvider)'. Then the dependency can only be fulfilled by a service matching this filter.
+
+Moreover, from attributes can be customized instance by instance. It is possible to specialize / change / add a 'from' attribute of a component in the instance configuration. It is useful when you want to create different instances of the same component, with different 'from' clauses. To do it, you have to identify your dependency with an 'id' attribute. Then, you can adapt the 'from' of the dependency in the instance configuration by using the property "requires.from". In this property you can specify each dependency identified by its id and the 'from' value.
+
+
+    <component 
+       className="org.apache.felix.ipojo.example.FilteredDependency"
+       name="FOO">
+    	<requires field="m_foo" id="id1">
+    		<callback type="bind" method="bind"/>
+    		<callback type="unbind" method="unbind"/>
+    	</requires>
+    </component>
+    
+    <instance name="FOO1" component="FOO"/>
+    
+    <instance name="FOO2" component="FOO">
+    	<property name="requires.from">
+    		<property name="id1" value="myprovider"/>
+    	</property>
+    </instance>
+    
+    <instance name="FOO3" component="FOO">
+    	<property name="requires.from">
+    		<property name="id1" value="myotherprovider"/>
+    	</property>
+    </instance>
+
+
+The FOO component type declares a service dependency with the 'id1' id. This dependency has no 'from' attribute by default. The first instance is just an instance of the FOO component type and does not modify the dependency. The second one adds a 'from' attribute to the declared dependency to target the 'myprovider' provider. The last one adds another 'from' clause to the declared dependency.
+
+
+## Binding Policies
+
+Three binding policies are supported inside iPOJO.
+* Dynamic policy (default): the binding are managed      dynamically. At each injection, the same provider is injected if the      provider is always available. Else a new one is chosen. For aggregate      dependency, the array order does not change; new providers are placed at      the end of the array.
+* Static policy: the binding is static. So, once      bound a provider cannot disappear. If it disappears, the instance is      invalidated and cannot be revalidated without stopping and restarting the      instance.
+* Dynamic-priority policy: the binding is managed      dynamically but the injected provider is selected by using a ranking      policy. Two injections can return two different providers, is a new      provider is 'better' than the previous one, despite the first one is always      available. For aggregate dependency, the array is sorted.
+
+
+A static binding is declared as following:
+
+    @Requires(policy="static")
+    private Hello[] m_hellos;
+
+or
+
+    <requires field="m_hellos" policy="static"/>
+
+
+A dynamic-priority binding is declared as following:
+
+    @Requires(policy="dynamic-priority")
+    private Hello[] m_hellos;
+
+or
+
+    <requires field="m_hellos" policy="dynamic-priority"/>
+
+
+By default, the dynamic-priority policy uses the OSGi service ranking policy. However, it is possible to customize the policy by adding the '*comparator*' attribute. This attribute indicates the class name of a class implementing the `java.util.Comparator` interface. iPOJO creates an instance of your comparator and uses it to sort service references (so your customized comparator needs to be able to sort OSGi Service Reference).
+
+    @Requires(policy="dynamic-priority", comparator=MyComparator.class)
+    private Hello[] m_hellos;
+
+or
+
+    <requires field="m_hellos" policy="dynamic-priority" comparator="great.MyComparator"/>
+
+
+
+## Note about nullable object & default-implementation
+
+The instance implementation can use an optional dependency without any checking. Indeed, when an instance declares an optional dependency using field injection, iPOJO create on the fly a Nullable class implementing the service specification but doing nothing (mock object). Therefore, iPOJO cannot return a service to the instance, for an optional dependency, it returns a nullable object.
+
+A nullable object returns:
+* Null when the method returns an object
+* 0 when the method returns an int, log, byte, short, char, float or a double
+* False when the method return a boolean
+
+You can check if the returned object is a nullable object with the test: *"myservice instanceof Nullable"*.
+
+You can disable the Nullable pattern too (activated by default). In this case, iPOJO injects `null` instead of a *Nullable* object. So, you can just test if your field is equals to *null* to check if the service is available. To disable the Nullable pattern, you need to add the 'nullable="false"' attribute in your service dependency description as follows:
+
+    @Requires(optional=true, nullable=false)
+    private LogService m_log;
+
+or
+
+     <requires field="m_log" optional="true" nullable="false"/>
+
+
+However, you can also indicate a *default-implementation* for your optional service. In this case, if no providers are found, iPOJO creates an instance of the default-implementation and injects it. The default-implementation attribute describes the class name of your implementation. The given class *MUST* implement the required service interface.
+
+For example, the following component uses a default implementation for a Log Service dependency:
+
+    @Requires(optional=true, default-implementation=MyLogService.class)
+    private LogService m_log;
+
+or
+
+    <requires field="m_log" optional="true" 
+        default-implementation=
+           "org.apache.felix.ipojo.example.default.MyLogService"/>
+
+If the log service is not available, iPOJO creates an object of the 'org.apache.felix.ipojo.example.default.MyLogService' class. This object is injected instead of a Nullable object. For instance, the default implementation can print messages on the System.err stream. The nullable object does no display anything.
+
+
+## Note about Callbacks
+Dependency manages two type of callback: bind and unbind. A callback with a type "bind" is called each type that a service provider arrives and the binding is necessary. According to the cardinality of the dependency it means:
+* Simple dependency : at the firs binding and at      each rebinding to another service provider
+* Aggregate dependencies: each time that a service      provider arrives
+
+An unbind callback is called each time that a *used* service provider goes away. For a simple dependency this method is called each time that the used service provider goes away. For a multiple dependency this method is called each time that a service provider goes away.
+
+The method can receive in argument the service object or the service reference (in order to obtain service properties). The bind methods are delayed since a POJO object is created.
+
+## Proxies
+Since iPOJO 1.6, iPOJO injects proxy objects. Those proxies are by default smart proxies and are design to be lightweight:
+* for scalar requirement : the service object is a proxy
+* for aggregate dependencies : iPOJO injects a smart collections
+
+The goal of the proxies is to hide the dynamism and more particularly the dynamism. So, you can gives a service dependency to another object, using the service object still supports the dynamism. For collections, you can iterate over the collection without managing the potential departures and arrivals of services. The proxy also manage that the component class and the delegate objects shared the same services is they are accessed in the same Thread.
+
+By default iPOJO injects proxy except for arrays. Moreover, it is possible to disable the proxy injection by adding `proxy=false` to the `requires` element (or to the `@Requires` and `@Bind` annotations). It is also possible to inject dynamic proxies (if the platform does not support dynamically generated classes). To enable dynamic proxies, set the system or bundle property `ipojo.proxy.type` to `dynamic-proxy`. You can also disable completely the proxy injection by setting the system property `ipojo.proxy` to `disabled`.
+
+
+
+## Note on service interface discovery
+
+The `specification` attribute is generally optional except when iPOJO cannot discover the type of the service. iPOJO cannot infer the type when the dependency has no field and callbacks do not receive the service object in parameter. In this case, you must the service specification (i.e. interface).
+  
+  
+  
+  
+{include:apache-felix-ipojo-footer}
\ No newline at end of file



Mime
View raw message