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

Compare with Current View Page History

« Previous Version 4 Next »

iPOJO defines several annotations to help developer to define their components. This page presents an example of iPOJO annotation and describes provided annotations.

Getting iPOJO Annotations:

iPOJO Annotations are defines inside the org.apache.felix.ipojo.annotations project. You can download the Jar file of this project here.
Once added to your class path / build path / dependencies, you can use the annotations as normal annotations. These annotations are automatically processed by the iPOJO manipulator.

In Eclipse:

Add the org.apache.felix.ipojo.annotations jar file in your build path. Do not forget to use a Java compiler accepting annotations (1.5 or higher).

In Maven:

Add the following dependency:

<dependency>
      <groupId>org.apache.felix</groupId>
      <artifactId>org.apache.felix.ipojo.annotations</artifactId>
      <version>0.7.3-SNAPSHOT</version>
</dependency>

Moreover, you need to set that the source code and the target code are Java 1.5 code. To achieve this, just add the following plugin in your plugins section:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<configuration>
	  <source>1.5</source>
	  <target>1.5</target>
	</configuration>
</plugin>

In Ant :

Just add the org.apache.felix.ipojo.annotations jar file in your class path.

An example of usage:

To illustrate annotations usage, let taking the tutorial example. In this tutorial, there are two components:

  • The first one provides the hello service
  • The second one uses the provided hello service
    You can download these projects here

Hello Service Provider

The provider uses two annotations. The "component" annotation is mandatory and defines that the class defines a component type. Then the "provides" annotation just declare that the defined component type provides a service.

package ipojo.example.hello.impl;

import ipojo.example.hello.Hello;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;

/**
  * Component implementing the Hello service.
 **/
@Component
@Provides
public class HelloImpl implements Hello {
    public String sayHello(String name) { return "hello " + name;  }
}

Hello Service Consumer

The Hello Service Consumer use more annotations. First it used the componenet annotation. To defines its "immediate" behavior, it add the 'immediate' attribute.
Then, it uses the requires annotation to define a service dependency. Finally, it uses the validate and invalidate annotations to define lifecycle callbacks.

package ipojo.example.hello.client;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Requires;
import org.apache.felix.ipojo.annotations.Validate;

import ipojo.example.hello.Hello;

@Component(name="AnnotedHelloClient", immediate=true)
public class HelloClient implements Runnable {

@Requires
private Hello[] m_hello; // Service Dependency

private final static int DELAY=10000;
private boolean end;

 public void run() {
    while (!end) {
               try {
		invoke();
                Thread.sleep(DELAY);
              } catch (InterruptedException ie) { }
              /* will recheck end */
     }
}

public void invoke() {
	for (int i = 0; i < m_hello.length; i++) { System.out.println(m_hello[i].sayHello("Clement")); }
}

 @Validate
 public void starting() {    Thread T = new Thread(this);     end = false;     T.start();   }
 
 @Invalidate
 public void stopping() {    end = true;  }
}

Defined Annotations

This section lists defined annotations and how to use them.

@Component

Goal: Defines a component type
Target: The component implementation class
Attributes:

  • name : defines the component type name (optional, default = the class name)
  • factory: defines the factory name (optional, default = "false")
  • immediate: defines the component type as immediate (optional, default = "false")
  • architecture: enable the architecture exposition (optional, default = "false")
  • propagation: enable configuration property propagation (on provided services) (optional, default = "false")

@Provides

Goal: Defines that the component type provide services
Target: The component implementation class
Attributes:

  • specification: defines the provided interface (optional, default = all implemented interfaces)
  • factory: defines the service object creation policy ("SINGLETON" or "FACTORY") (optional, default = "SINGLETON")

Note: "FACTORY" means OSGi service factory.

@Requires

Goal: Defines a service dependency
Target: Field
Attributes:

  • Filter: defines the LDAP filter (optional)
  • Optional: defines if the dependency is optional (optional, default = "false")
  • Id: defines the dependency Id (useful to identify bind & unbind methods) (optional, default = field name) (if a dependency with the same id is already created (by a @bind or @unbind annotation), it merges the dependencies).

@ServiceProperty

Goal: Defines a service property
Target: Field
Attributes:

  • name: property name (optional, default=field name)
  • value: property value (optional, default=no value)

@Property

Goal: Defines a property
Target: Field
Attributes:

  • name: property name (optional, default=field name)
  • value: property value (optional, default=no value)

@Bind

Goal: Defines a bind method
Target: Method
Attributes:

  • Id: Dependency Id, if the id is already defines in a "@requires " or "@unbind" annotation, it adds this method as a bind method of the already created dependency. (optional, default= no id, compute an id if the method name begin by "bind" (for instance "bindFoo" will have the "Foo" id))
  • Specification : required dependency (optional)
  • Aggregate : is the dependency an aggregate dependency (optional, default= "false")
  • Optional: is the dependency an optional dependency (optional, default= "false")
  • Filter: dependency LDAP filter (optional)

@Unbind

Goal: Defines an unbind method
Target: Method
Attributes:

  • Id: Dependency Id, if the id is already defines in a "@requires" or "@bind" annotation, it adds this method as an unbind method of the already created dependency. (optional, default= no id, compute an id if the method name begin by "unbind" (for instance "unbindFoo" will have the "Foo" id))
  • Specification : required dependency (optional)
  • Aggregate : is the dependency an aggregate dependency (optional, default= "false")
  • Optional: is the dependency an optional dependency (optional, default= "false")
  • Filter: dependency LDAP filter (optional)

@Validate

Goal: defines a validate lifecycle callback
Target: method

@Invalidate

Goal: defines a validate lifecycle callback
Target: method

Metadata file and annotation merge

It is possible to defines component type both in the metadata file (in XML) and by using annotation. However, if a component type defined by using annotations has the same name than a type define in the XML file, the XML descriptor override the annotation defined type. However, a warning message is launched during the manipulation.

Instance creation

Annotation can only be used to define component type. To define instances, you need to use the XML descriptor. Instance can refer to annotated types by referring to their names.

<instance component="ipojo.example.hello.impl.HelloImpl"/>
<instance component="AnnotedHelloClient"/>

Generic Annotations

To support external handlers, iPOJO defines two generic annotations. These annotations can be used if you want to use an external handler. However, due to annotation limitation, not all external handlers can be used with these annotations.

@Element

Goal: defines an element
Target: component implementation class
Attributes:

  • Name : element name (mandatory)
  • Namespace: element namespace (mandatory)
  • Attributes: array of @Attribute (optional)
  • Elements: array of @SubElement (optional)

@Attributes

Goal: defines an element attribute
Attributes:

  • Name: attribute name
  • Value: attribute value

@SubElement

Goal: defines an sub-element
Attributes:

  • Name : element name (mandatory)
  • Namespace: element namespace (mandatory)
  • Attributes: array of @Attribute (optional)
  • No labels