You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 14 Next »

Declaring component types

XML
<component
    classname="my.Implementation"
    name="my-type">
</component>
Annotations
@Component(name="my-type")
public class Implementation {
  // ...
}

Creating component instances

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

Providing services

XML
<component classname="my.service.implementation" name="my-service-impl">
   <provides/>
</component>
<instance name="my-service-impl"/>
Annotations
@Component
@Provides
public class Implementation implements FooService {
   ...
}
  • Only instances provides really services, so don't forget to declare an instance.
  • Published service interfaces must be implemented by your component implementation
  • Providing OSGi services

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/>
Annotations
@Component
@Provides(specifications= {FooService.class, BarService.class})
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

XML
<component classname="my.consumer.Implementation">
    <requires field="fs" />
</component>
Annotations
@Component
public class Dependency {

    @Requires
    public FooService fs;
    
    //...
}

Using services with method injection

XML
<component classname="my.consumer.Implementation">
    <requires>
	<callback type="bind" method="bind" />
	<callback type="unbind" method="unbind" />
    </requires>	
</component>
Annotations
@Component
public class Dependency {

    @Unbind
    public synchronized void unbind(BazService bz) {
        //...
    }
    
    @Bind
    public synchronized void bind(BazService bz) {
        // ...
    }

  //...
}

Reacting to lifecycle state changes

Immediate components

  • A POJO object (implementation object) is created as soons as the instance becomes valid
  • Instances that don't provide services becomes automatically immediate
    XML
    <component classname="my.service.implementation" name="my-service-impl" immediate="true">
       <provides/>
    </component>
    
    Annotations
    @Component(immediate=true)
    @Provides
    public class Implementation implements FooService {
       ...
    }
    
  • Lifecycle Callback Handler

Lifecycle callbacks

XML
<component classname="my.implementation" name="my-impl">
    <callback transition="validate" method="start" />
    <callback transition="invalidate" method="stop" />
</component>
Annotations
@Component
public class Implementation {
    
    @Validate
    public void start() {
        
    }
    
    @Invalidate
    public void stop() {
        
    }
}

Declaring properties

XML
<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>
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;
}

Using 'arch'

  • Deploy the 'arch' command bundle (available for Felix and Equinox)
  • Launch the 'arch' command in the OSGi Framework Shell
    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
    
  • iPOJO Arch Command
  • Architecture Handler

Temporal Dependencies

  • 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.
XML
<iPOJO xmlns:temporal="org.apache.felix.ipojo.handler.temporal">
<component
    className="my.Implementation">

    <!-- Temporal dependency configuration -->
    <temporal:requires field="mytemporal"/>
    <provides/>
</component>
</iPOJO>
Annotations
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;
    
}

Sending and receiving events

Receiving events

  • 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.
XML
<ipojo
    xmlns:ev="org.apache.felix.ipojo.handlers.event.EventAdminHandler">
	<component className="...MyComponent">
		<ev:subscriber
			name="mySubscriber"
			callback="receive"
			topics="foo"/>
	</component>
</ipojo>
Annotations
@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
Instance configuration
<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>

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 org.apache.felix.ipojo.handlers.event.publisher.Publisher 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>
Annotations

@Component
public class MyComponent {
    @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
Instance configuration
<instance component="...MyComponent">
		<property name="event.topics">
			<property name="myPublisher" value="foo"/>
		</property>
	</instance>

Extender Pattern

  • 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.
XML
<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>

Annotations
@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
    }
}

Whiteboard Pattern

  • 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.
XML
<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>
Annotations
@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) {
        // nothing
    }
    
    public void onDeparture(ServiceReference ref) {
        // nothing
    }
    
    public void onModification(ServiceReference ref) {
        // nothing
    }

}
Error CSS Stylesheet macro - Import URL 'http://people.apache.org/~clement/ipojo/ipojo.css' is not on the allowlist. If you want to include this content, contact your Confluence administrator to request adding this URL to the Allowlist.

Overview
Getting Started
User Guide
Tools
Developer Guide
Misc & Contact
Experimentation

  • No labels