Declaring component types

XML:

<component
    classname="my.Implementation"
    name="my-type">
</component>

Java:

@Component(name="my-type")
public class Implementation {
  // ...
}
Attribute name Required Default value Description
classname yes indicates the implementation class (automatic when using annotations).
name no the implementation class name specifies the component class name

Creating component instances

XML:

<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>

Java:

@Component(name="my-type")
@Instantiate
public class Implementation {
  // ...
}
Attribute name Required Default value Description
component yes specifies the component type (either by using the name or the class name)
name no generated specifies the instance name.

Providing services

XML:

<component classname="my.service.implementation" name="my-service-impl">
   <provides/>
</component>
<instance name="my-service-impl"/>

Java:

@Component
@Provides
public class Implementation implements FooService {
   ...
}
Attribute name Required Default value Description
specifications no all implemented interfaces specifies the published service interfaces
strategy no `singleton` specifies the service object creation policy among `singleton`, `service` (OSGi Service Factory), `method` (use the factory method), `instance` (an object per instance)

Publishing service properties

XML:

<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/>

Java:

@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;

    // ...
}
Attribute name Required Default value Description
name no the field name specifies the published property name
mandatory no false specifies if the property has to receive a value from the instance configuration
value no specifies the default property value
field no (automatic with annotations) specifies the injected field
type only if there is no fields specified the property type

Using services with field injection

XML:

<component classname="my.consumer.Implementation">
    <requires field="fs" />
    <requires field="bs" />
</component>

Java:

@Component
public class Dependency {

    @Requires
    public FooService fs;

    @Requires
    public BarService[] bs;

    //...
}
Attribute name Required Default value Description
id no field name dependency id
field no automatically detected with annotations injected field
optional no false specifies if the dependency if optional
aggregate no false
(automatically detected with fields)
specifies if the dependency is aggregate of scalar
specification yes/no can be discovered from the code specifies the required service specification. This attribute is required when the service type cannot be inferred from the code (Collection type for fields, callbacks without service objects)
filter no no filter specifies the dependency LDAP filter
from no   specifies a specific provider by its name
policy no dynamic specifies the binding policy among dynamic, static and dynamic-priority
nullable no true enables/disables nullable object injection for optional dependencies
default-implementation // defaultimplementation for annotations no   specifies the default-implementation for optional dependencies
comparator no   specifies the comparator class used to sort service providers

Using services with method injection

XML:

<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>

Java:

@Component
public class Dependency {

    @Unbind
    public synchronized void unbindBaz(BazService bz) {
        //...
    }

    @Bind
    public synchronized void bindBaz(BazService bz) {
        // ...
    }

    @Modified
    public synchronized void modifiedBaz() {
        // ...
    }

  //...
}

{div:class=borderedTable} {center} |Attribute name | Required | Default value | | |--|--|--|--| | id | no | field name | dependency id | | field | no | automatically detected with annotations | injected field | | optional | no | false | specifies if the dependency if optional |

| specification | yes/no | can be discovered from the code | specifies the required service specification. This attribute is required when the service type cannot be infered from the code (Collection type for fields, callbacks without service objects) | | filter | no | no filter | specifies the dependency LDAP filter | | from | no | | specifies a specific provider by its name | | policy | no | dynamic | specifies the binding policy among dynamic, static and dynamic-priority | | nullable | no | true | enables/disables nullable object injection for optional dependencies | | default-implementation // default implementation for annotations | no | | specifies the default-implementation for optional dependencies | | comparator | no | | specifies the comparator class used to sort service providers |

Sub-Element name Required Default value
callback no callback specifies bind and unbind method. Two attributes are required (discovered automatically with annotations). type specified if the callback is a bind or unbind method (among `{bind,unbind,modified\}. Themethodattribute specified the method to call. Themodified` callback is called when the service properties of a bound service are modified and the service still match the filter.
* Service Requirement Handler

Configuring service dependencies in the instance configuration

h2. Configuring the from attribute * Thanks to the requires.from property, it is possible to override the from attribute value.

{code:xml|From attribute configuration}

 h2. Configuring the  attribute
* Thanks to the  property, it is possible to override the  attribute value.

{code:xml|Filter attribute configuration}
<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>

Reacting to lifecycle state changes

Immediate components

{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 | {center} {div} * Lifecycle Callback Handler

Lifecycle callbacks

{code:java|title=Annotations}
@Component
public class Implementation {

    @Validate
    public void start() {

    }

    @Invalidate
    public void stop() {

    }
}

Declaring properties

{code:java|title=Annotations}
@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;
}

{div:class=borderedTable} {center} |Attribute name | Required | Default value | | |--|--|--|--| | propagation | no | false | specifies if the properties propagation (properties are also published as service properties) is enabled or disabled | | managedservice | no | instance name | specifies the PID of the published managed service. // This value can be overidden by the managed.service.pid instance property | | name | no | field name or computed from the method name | specifies if the the property name | | value | no | | specifies the default property value | | field | no | automatically detected with annotations | specifies the field in which the property value will be injected | | method | no | automatically detected with annotations | specifies the setter method in which the property value will be injected | | mandatory | no | false | specifies if the property has to receive a value from the instance configuration | {center} {div} * Configuration Handler

PostRegistration and PostUnregistration callbacks

Controlling service publication

Using 'arch'

Temporal Dependencies

{div:class=borderedTable} {center} |Attribute name | Required | Default value | | |--|--|--|--| | field | no | automatically detected with annotations | specifies the field in which the service object will be injected | | timeout | no | 3000 ms | specifies the timeout value (in ms). When the timeout is reached, the on timeout policy is executed | | onTimeout | no | Runtime Exception | specifies the on timeout policy. Possible values are: null, nullable, empty, default-implementation (class name) | | specification | only when using Collections | | specifies the required service specification. This attribute is required when the injected field is a Collection | | proxy | no | false | enables/disables proxy injection. Service injected as proxies can be given to collaborators | | filter | no | no filter | Filter use to discover matching filter. | {center} {div} * Temporal Service Dependency

Sending and receiving events

Receiving events

{div:class=borderedTable} {center} |Attribute name | Required | Default value | | |--|--|--|--| | name | yes | | specifies the name of the event subscriber, acting as a unique identifier. This name is used to configure event subscription in the instance configuration. |

| topics | yes | | specifies the list (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. This parameter can be overridden by instances |

If you use this attribute, the parameter passed to the callback method is the the value associated to this key, not the whole event. This attribute is generally used with the data-type attribute to specify the received object type. If an event is received and it does not contain such a key, it is ignored (with a warning message). |

| filter | no | no filter | specifies the event LDAP filter 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. | {center} {div} * Instance configuration event.topics : overrides topics attribute event.filter : overrides filter attribute

{code:xml|title=Instance configuration}

* [Event Admin Handlers]

h2. Sending events

 * 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  field.

    :::xml
<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:java|title=Annotations}

@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);
}

}

* [Event Admin Handlers]

{div:class=borderedTable}
{center}
||Attribute name || Required || Default value || ||
| name | yes | | specifies the name of the event publisher, acting as a unique identifier. This name is used to configure event publishing in the instance configuration. |
| field | yes \\ automatically detected with annotations | | specifies The name of the field used to send events. The field is initialized at component instantiation time. The type of the field must be : . |
| topics | yes | | specifies the list (comma-separated-list) of the topics on which events will be sent. This parameter can be overridden by instances |
| data-key \\ data_key when using annotations | no | user.data | specifies the data key used when you want to send data events.  This attribute's value is the key, in the event's dictionary, in which sent data are stored. When you use the _sendData_ method of the Publisher, the given object is placed in the event dictionary, associated with the specified data-key.  |
| synchronous | no | false | specifies if event sending is synchronous or not.   |
{center}
{div}

* Instance configuration
    ** event.topics : overrides  attribute

{code:xml|title=Instance configuration}
<instance component="...MyComponent">
        <property name="event.topics">
            <property name="myPublisher" value="foo"/>
        </property>
    </instance>

Extender Pattern

{div:class=borderedTable} {center} |Attribute name | Required | Default value | | |--|--|--|--| | extension | yes | | specifies the required extension (i.e. the required Manifest key) | | onArrival | yes | | specifies the method called when a matching bundle arrives. The method receives the Bundle object and the extension value | | onDeparture | yes | | specifies the method called when a matching bundle leaves. The method receives the Bundle object | {center} {div} * Extender Pattern Handler

Whiteboard Pattern

{center} |Attribute name | Required | Default value | | |--|--|--|--| | filter | yes | | specifies LDAP filter used to detect required service providers | | onArrival | yes | | specifies the method called when a matching service provider arrives. The method receives the ServiceReference object | | onDeparture | yes | | specifies the method called when a matching service provider leaves. The method receives the ServiceReference object | | omModification | no | | specifies the method called when a matching service provider is modified and is still matching. The method receives the ServiceReference object | {center} * White Board Pattern Handler