Writing custom annotation processor in J2SE 6


 In this post let us discuss how to write a simple custom annotation processor in J2SE 6. Let us begin with our annotation Requirement which is very simple and has an id and description as below.

package com.ts.customannot;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Requirement {

    String id();
    String desc();

}

We can use this annotation in any of our class as below. Here as an example I have used it in StudentService.java as below.

package com.ts.annot.target;

import com.ts.customannot.Requirement;


@Requirement(id="12",desc="student maintenance")
public class StudentService {

    public String getStudentName(String id){
        return "Student's Name";
    }

   
}

 

Now let us write a custom annotation processor which will look for the annotation requirement and print the value of id and desc.

package com.ts.annot.processor;

import com.ts.customannot.Requirement;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

/**
 *
 * @author karthikeyanc
 */

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("com.ts.customannot.Requirement")
public class CustomProcessor extends AbstractProcessor {

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

        if (!roundEnv.processingOver()) {
            try {
                Class reqClass = Class.forName("com.ts.customannot.Requirement");

                for (Element element : roundEnv.getRootElements()) {

                    Requirement reqObj = (Requirement) element.getAnnotation(reqClass);

                    if (reqObj != null) {
                        System.out.println(reqObj.id() + " : " + reqObj.desc());

                    }
                }



            } catch (Exception ex) {
                Logger.getLogger(CustomProcessor.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

        return false; // No annotations claimed

    }
}

We need to invoke this CustomProcessor. So let us write a Main class  which will act as the starting point. The argument to this Main class will be the root source folder containing Java files.


import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

    /**
     * @param args the command line arguments arg[0] is the root src folder.
     */
    public static void main(String[] args) {
      
        try {
            File srcFolder = new File(args[0]);
            processFile(srcFolder);

        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

    private static void processFile(File file) throws IOException {
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                processFile(child);
            }
            processForAnnotation(file);
        }
    }

   
   
    private static void processForAnnotation(File file) throws IOException {
      
        String str = "javac  -cp .\\build\\classes -processor  com.ts.annot.processor.CustomProcessor -proc:only " + file.getAbsolutePath() + File.separator + "*.java";   

        //Just obtain and print the console output.
        Process proc=Runtime.getRuntime().exec(str);
        InputStream is=proc.getInputStream();
        BufferedReader br=new BufferedReader(new InputStreamReader(is));
        String line=null;
        while( (line=br.readLine())!=null){
            System.out.println(line);
        }
     
        br.close();
       
    }
}

Below is the screenshot of running Main and the output obtained [In my example args[0] is E:\javacode\netbeanscode\CustomAnnotationProcessor\src] where CustomAnnotationProcessor is the project root folder.



 
 
 
 
Comments:

Post a Comment:
  • HTML Syntax: Allowed
 

« January 2009
SunMonTueWedThuFriSat
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
       
Today

Valid XHTML or CSS?

[This is a Roller site]
 
© Karthik