THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
...
Declaring component types
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<component classname="my.Implementation" name="my-type"> </component> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component(name="my-type") public class Implementation { // ... } |
...
Creating component instances
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<instance component="my-type"/> <instance component="my.Implementation"/> <instance component="my-type" name="my-instance"/> <instance component="my-type" name="my-instance"> <property name="property1" value="value1"/> </instance> |
...
- Instances can contains a configuration given under the
key-value
form. Properties can also by complex type. - How-to use iPOJO factories
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component(name="my-type") @Instantiate public class Implementation { // ... } |
Providing services
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.service.implementation" name="my-service-impl"> <provides/> </component> <instance name="my-service-impl"/> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component @Provides public class Implementation implements FooService { ... } |
...
Publishing service properties
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<component classname="my.service.implementation" name="my-service-impl"> <provides> <property name="foo" field="m_foo" /> <property name="bar" field="m_bar" mandatory="true" /> <property name="baz" type="java.lang.String" /> <!-- Static property (do not change at runtime) --> </provides> </component> <instance name="my-service-impl"> <!-- The configuration has to inject value in unvalued mandatory properties --> <property name="bar" value="5"/> <property name="baz" value="my string"/> <instance/> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component @Provides(specifications= {FooService.class, BarService.class}, properties= { @StaticServiceProperty(name="baz", type="java.lang.String")}) public class ProvidesProperties implements FooService, BarService { @ServiceProperty(name = "foo") public int m_foo = 0; @ServiceProperty(name="bar", mandatory=true) public int m_bar; // ... } |
...
Using services with field injection
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<component classname="my.consumer.Implementation"> <requires field="fs" /> <requires field="bs" /> </component> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component public class Dependency { @Requires public FooService fs; @Requires public BarService[] bs; //... } |
...
Using services with method injection
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.consumer.Implementation"> <requires> <callback type="bind" method="bind" /> <callback type="unbind" method="unbind" /> <callback type="modified" method="modified" /> <!-- for filtered service dependencies, to be notified when a service is modified but still match --> </requires> </component> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component public class Dependency { @Unbind public synchronized void unbindBaz(BazService bz) { //... } @Bind public synchronized void bindBaz(BazService bz) { // ... } @Modified public synchronized void modifiedBaz() { // ... } //... } |
...
- Thanks to the
requires.from
property, it is possible to override thefrom
attribute value.
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<component classname="...MyComponent" 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"/> <!-- Use the default 'from' value --> <instance name="FOO2" component="FOO"> <property name="requires.from"> <property name="id1" value="myprovider"/> </property> </instance> |
...
- Thanks to the
requires.filters
property, it is possible to override thefilter
attribute value.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="org.apache.felix.ipojo.example.FilteredDependency" name="FOO"> <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"/> <!-- Use the default 'filter' value --> <instance name="FOO2" component="FOO"> <property name="requires.filters"> <property name="id1" value="(foo.property=BAR)"/> </property> </instance> |
...
- A POJO object (implementation object) is created as soons as the instance becomes valid
- Instances that don't provide services becomes automatically immediate
Code Block xml xml title XML xml <component classname="my.service.implementation" name="my-service-impl" immediate="true"> <provides/> </component>
Code Block java java title Annotationsjava @Component(immediate=true) @Provides public class Implementation implements FooService { ... }
Div class borderedTable Center Attribute name
Required
Default value
immediate
no
false // true for instances that don't provide a service
specifies if the instance is immediate or not
- Lifecycle Callback Handler
Lifecycle callbacks
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<component classname="my.implementation" name="my-impl"> <callback transition="validate" method="start" /> <callback transition="invalidate" method="stop" /> </component> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component public class Implementation { @Validate public void start() { } @Invalidate public void stop() { } } |
...
Declaring properties
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.Implementation" name="my-impl"> <properties propagation="true" managedservice="MyPID"> <property name="boo" method="setBoo" /> <property field="m_bar" mandatory="true"/> <property field="m_foo" value="4"/> </properties> </component> <instance component="my-impl"> <property name="boo" value="..."/> <property name="m_bar" value="..."/> </instance> <instance component="my-impl"> <property name="boo" value="..."/> <property name="m_bar" value="..."/> <property name="managed.service.pid" value="AnotherPID"/> </instance> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component(managedservice="MyPID", propagation=true) public class Implementation { @Property(name="boo") public void setBoo(int boo) { //... } @Property(mandatory=true) public int m_bar; @Property(value="4") public int m_foo; } |
...
- This feature is part of the provided service handler, and so requires that the component provides a service.
- The callback receives a
ServiceReference
as parameter.Code Block xml xml title XML xml <component classname="..."> <provides post-unregistration="unregistered" post-registration="registered"/> </component>
Code Block java java title Annotations java @PostRegistration public void registered(ServiceReference ref) { System.out.println("Registered"); } @PostUnregistration public void unregistered(ServiceReference ref) { System.out.println("Unregistered"); }
- Provided Service Handler
...
- This feature is part of the provided service handler, and so requires that the component provides a service.
- It allows a component to force the un-publication of a service.
Code Block xml xml title XML xml <component classname="..."> <provides> <controller field="controller" value="false"/> </provides> </component>
Code Block java java title Annotationsjava @ServiceController(value="false") private boolean controller
- Provided Service Handler
...
- Deploy the 'arch' command bundle (available for Felix and Equinox)
- Launch the 'arch' command in the OSGi Framework Shell
Code Block java java title Felix Shelljava arch => displays instances name & state (equivalent to arch \-instances) arch -instance $instance_name => displays complete information about the instance $instance_name arch -factories => display the list of available factories arch -factory $factory_name => display complete information about the factory $factory_name arch -handlers => list available handlers
Code Block java java title Felix Gogo java ipojo:instances => displays instances name & state (equivalent to arch \-instances) ipojo:instance $instance_name => displays complete information about the instance $instance_name ipojo:factories => display the list of available factories ipojo:factory $factory_name => display complete information about the factory $factory_name ipojo:handlers => list available handlers
...
- Temporal dependencies are injected in fields. When accessing to the service, the thread waits for the service availability. If a timeout is reached, a timeout policy is executed.
- Service objects can be injected as
proxies
and be given to collaborator objects. - Temporal dependencies are implemented as an external handlers. To use them, deploy and start the temporal dependency handler bundle.
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<iPOJO xmlns:temporal="org.apache.felix.ipojo.handler.temporal"> <component className="my.Implementation"> <!-- Temporal dependency configuration --> <temporal:requires field="mytemporal"/> <provides/> </component> </iPOJO> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.handler.temporal.Requires; import org.apache.felix.ipojo.test.scenarios.annotations.service.FooService; @Component public class Implementation { @Requires // org.apache.felix.ipojo.handler.temporal.Requires private FooService mytemporal; } |
...
- The event admin handler allows receiving events from the Event Admin.
- The event admin handler is implemented as an external handlers. To use it, deploy and start the event admin handler bundle and an implementation of the event admin service.
- Event (or data) are receive thanks to a callback method.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<ipojo xmlns:ev="org.apache.felix.ipojo.handlers.event.EventAdminHandler"> <component className="...MyComponent"> <ev:subscriber name="mySubscriber" callback="receive" topics="foo"/> </component> </ipojo> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component public class MyComponent { @Subscriber(name="s1", data_key="data") public void receive1(Object foo) { // Nothing } @Subscriber(name="s2", topics="foo,bar", filter="(foo=true)") public void receive2(Event foo) { // Nothing } @Subscriber(name="s3", topics="foo", data_key="data", data_type="java.lang.String") public void receive3(String foo) { // Nothing } |
...
- Instance configuration
- event.topics : overrides
topics
attribute - event.filter : overrides
filter
attribute
- event.topics : overrides
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<instance component="...MyComponent"> <property name="event.topics"> <property name="mySubscriber" value="foo"/> </property> <property name="event.filter"> <property name="mySubscriber" value="|((arg=Minibar)(arg=Coconuts))"/> </property> </instance> |
...
- The event admin handler allows sending events to the Event Admin.
- The event admin handler is implemented as an external handlers. To use it, deploy and start the event admin handler bundle and an implementation of the event admin service.
- To send events, your code must contains a
org.apache.felix.ipojo.handlers.event.publisher.Publisher
field.
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<ipojo xmlns:ev="org.apache.felix.ipojo.handlers.event.EventAdminHandler"> <component className="...MyComponent"> <ev:publisher name="myPublisher" field="m_publisher" topics="bar,nuts"/> </component> <instance component="...MyComponent"/> </ipojo> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component public class MyComponent { // We use qualified names to avoid conflict. @org.apache.felix.ipojo.handlers.event.Publisher(name="p1", synchronous=true) org.apache.felix.ipojo.handlers.event.publisher.Publisher publisher1; @org.apache.felix.ipojo.handlers.event.Publisher(name="p2", synchronous=false, topics="foo,bar", data_key="data") org.apache.felix.ipojo.handlers.event.publisher.Publisher publisher2; @org.apache.felix.ipojo.handlers.event.Publisher(name="p3", synchronous=true, topics="bar") org.apache.felix.ipojo.handlers.event.publisher.Publisher publisher3; // ... public void doSomething() { Dictionary e = new Properties(); //... // Fill out the event // Send event publisher1.send(e); } } |
...
- Instance configuration
- event.topics : overrides
topics
attribute
- event.topics : overrides
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<instance component="...MyComponent"> <property name="event.topics"> <property name="myPublisher" value="foo"/> </property> </instance> |
...
- Allows implementing an
Extender pattern
without handling obscure details - The extender pattern handler is implemented as an external handlers. To use it, deploy and start the external pattern handler bundle.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<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="onArrival" onDeparture="onDeparture" /> <callback transition="invalidate" method="stopping" /> <callback transition="validate" method="starting" /> </component> </ipojo> |
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
@Component @org.apache.felix.ipojo.extender.Extender(extension="My-Extension", onArrival="onArrival", onDeparture="onDeparture") public class Myextender { public void onArrival(Bundle bundle, String extension) { // handle matching bundle arrival } public void onDeparture(Bundle bundle) { // handler matching bundle departure } } |
...
- Allows implementing a
Whiteboard pattern
without handling obscure details - The whiteboard pattern handler is implemented as an external handlers. To use it, deploy and start the whiteboard pattern handler bundle.
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
<ipojo xmlns:wbp="org.apache.felix.ipojo.whiteboard"> <component classname="org.apache.felix.ipojo.test.MyWhiteBoardPattern" > <wbp:wbp filter="(my.property=1)" onArrival="onArrival" onDeparture="onDeparture" onModification="onModification" /> <provides/> </component> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component @org.apache.felix.ipojo.whiteboard.Wbp(filter="(my.property=1)", onArrival="onArrival", onDeparture="onDeparture", onModification="onModification") public class WhiteBoardWIModification { public void onArrival(ServiceReference ref) { // ... } public void onDeparture(ServiceReference ref) { // ... } public void onModification(ServiceReference ref) { // ... } } |
...