Thursday, February 17, 2011

Java 6.0 Features Part - 2 : Pluggable Annotation Processing API

1) Introduction

The first part of this article listed out the major new features of Java 6 (Mustang) related to areas like Common Annotations (JSR 250), Scripting Language for the Java Platform (JSR 223) and JDBC 4.0. This article assumed that Readers have got sufficiently fair bit of knowledge in the various concepts of Java 5.0. First-time Readers of Java 6 are strongly encouraged to read the first part of this article titled "Introduction to Java 6.0 New Features, Part–I". This article covers the left-over features of Part-I. More specifically, it will cover the Pluggabable Annotation Processing API (JSR 269), Java API for XML Binding (JSR 222) and Streaming API for XML (JSR 173).
2) Pluggable Annotation Processing API
2.1) Introduction to Annotation

Annotations have been there in the Java World from Java 5.0. Java Annotations are a result of the JSR 175 which aimed in providing a Meta-Data Facility to the Java Programming Language. It can be greatly used by the Build-time Tools and Run-time Environments to do a bunch of useful tasks like Code Generation, Validation and other valuable stuffs. Java 6 has introduced a new JSR called JSR 269, which is the Pluggable Annotation Processing API. With this API, now it is possible for the Application Developers to write a Customized Annotation Processor which can be plugged-in to the code to operate on the set of Annotations that appear in a Source File.

Let us see in the subsequent sections how to write a Java File which will make use of Custom Annotations along with a CustomAnnotation Processor to process them.
2.2) Writing Custom Annotations

This section provides two Custom Annotations which will be used by a Sample Java File and a Custom Annotation Processor. One is the Class Level Annotation and the other is the Method Level Annotation. Following is the listing for both the Annotation Declarations. See how the Targets for the Annotations ClassLevelAnnotation.java and MethodLevelAnnotation.java are set to ElementType.TYPE and ElementType.METHOD respectively.

ClassLevelAnnotation.java


package net.javabeat.articles.java6.newfeatures.customannotations;

import java.lang.annotation.*;

@Target(value = {ElementType.TYPE})
public @interface ClassLevelAnnotation {
}


MethodLevelAnnotation.java


package net.javabeat.articles.java6.newfeatures.customannotations;

import java.lang.annotation.*;

@Target(value = {ElementType.METHOD})
public @interface MethodLevelAnnotation {
}


AnnotatedJavaFile.java


package net.javabeat.articles.java6.newfeatures.customannotations;

@ClassLevelAnnotation()
public class AnnotatedJavaFile {

@MethodLevelAnnotation
public void annotatedMethod(){
}
}


The above is a Sample Java File that makes use of the Class Level and the Method Level Annotations. Note that @ClassLevelAnnotation is applied at the Class Level and the @MethodLevelAnnotation is applied at the method Level. This is because both the Annotation Types have been defined to be tagged to these respective Elements only with the help of @Target Annotation.
2.3) Writing a Simple Custom Annotation Processor

TestAnnotationProcessor.java


package net.javabeat.articles.java6.newfeatures.customannotations;

import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;

@SupportedAnnotationTypes(value= {"*"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)

public class TestAnnotationProcessor extends AbstractProcessor {

@Override
public boolean process(
Set extends TypeElement> annotations, RoundEnvironment roundEnv){

for (TypeElement element : annotations){
System.out.println(element.getQualifiedName());
}
return true;
}
}


Let us discuss the core points in writing a Custom Annotation Processor in Java 6. The first notable thing is that Test Annotation Processor class extends AbstractProcessor class which encapsulates an Abstract Annotation Processor. We have to inform what Annotation Types our Test Annotation Processor Supports. This is manifested through the Class-Level Annotation called @SupportedAnnotationTypes(). A value of "*" indicates that all types of Annotations will be processed by this Annotation Processor. Which version of Source Files this Annotation Processor supports is mentioned through @SupportedSourceVersion Annotation.

The javac compiler of Mustang has an option called '-processor' where we can specify the Name of the Annotation Processor along with a Set of Java Source Files containing the Annotations. For example, in our case, the command syntax would be something like the following,


javac -processor
net.javabeat.articles.java6.newfeatures.customannotations.TestAnnotationProcessor
AnnotatedJavaFile.java


The above command tells that the name of the Annotation Processor is net.javabeat.articles.java6.newfeatures.customannotations.TestAnnotationProcessor and it is going to process the AnnotatedJavaFile.java. As soon as this command is issued in the console, the TestAnnotationProcessor.process() method will be called by passing the Set of Annotations that are found in the Source Files along with the Annotation Processing Information as represented by RoundEnvironment. This TestAnnotationProcessor just list the various Annotations present in the Sample Java File (AnnotatedJavaFile.java) by iterating over it.

Following is the output of the above program


net.javabeat.articles.java6.newfeatures.customannotations.ClassLevelAnnotation
net.javabeat.articles.java6.newfeatures.customannotations.MethodLevelAnnotation

SOURCE:http://www.javabeat.net/articles/14-java-60-features-part-2-pluggable-annotation-proce-1.html

0 comments: