Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Declaring component types

Code Block
xml
xml
titleXMLxml
<component
    classname="my.Implementation"
    name="my-type">
</component>
Code Block
java
java
titleAnnotationsjava
@Component(name="my-type")
public class Implementation {
  // ...
}

...

Creating component instances

Code Block
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@Component(name="my-type")
@Instantiate
public class Implementation {
  // ...
}

Providing services

Code Block
xml
xml
titleXMLxml
<component classname="my.service.implementation" name="my-service-impl">
   <provides/>
</component>
<instance name="my-service-impl"/>
Code Block
java
java
titleAnnotationsjava
@Component
@Provides
public class Implementation implements FooService {
   ...
}

...

Publishing service properties

Code Block
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@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
xml
xml
titleXMLxml
<component classname="my.consumer.Implementation">
    <requires field="fs" />
    <requires field="bs" />
</component>
Code Block
java
java
titleAnnotationsjava
@Component
public class Dependency {

    @Requires
    public FooService fs;

    @Requires
    public BarService[] bs;
    
    //...
}

...

Using services with method injection

Code Block
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@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 the from attribute value.
Code Block
xml
xml
1From attribute configurationxml
<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 the filter attribute value.
Code Block
xml
xml
1Filter attribute configurationxml
<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
    titleXMLxml
    <component classname="my.service.implementation" name="my-service-impl" immediate="true">
       <provides/>
    </component>
    
    Code Block
    java
    java
    titleAnnotationsjava
    @Component(immediate=true)
    @Provides
    public class Implementation implements FooService {
       ...
    }
    
    Div
    classborderedTable
    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
xml
xml
titleXMLxml
<component classname="my.implementation" name="my-impl">
    <callback transition="validate" method="start" />
    <callback transition="invalidate" method="stop" />
</component>
Code Block
java
java
titleAnnotationsjava
@Component
public class Implementation {
    
    @Validate
    public void start() {
        
    }
    
    @Invalidate
    public void stop() {
        
    }
}

...

Declaring properties

Code Block
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@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
    titleXMLxml
    <component
         classname="...">
        <provides
    	post-unregistration="unregistered" post-registration="registered"/>
    </component>
    
    Code Block
    java
    java
    titleAnnotationsjava
    @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
    titleXMLxml
    <component
         classname="...">
        <provides>
            <controller field="controller" value="false"/>
        </provides>
    </component>
    
    Code Block
    java
    java
    titleAnnotationsjava
    @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
    titleFelix 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
    titleFelix Gogojava
    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
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
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
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@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
Code Block
xml
xml
titleInstance configurationxml
<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
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava

@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
Code Block
xml
xml
titleInstance configurationxml
<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
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@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
xml
xml
titleXMLxml
<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
java
java
titleAnnotationsjava
@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) {
        // ...
    }

}

...