8

I am trying to write an annotation processor using java. This annotation processor needs to identify annotated nested classes within an annotated class as seen below. I will process the annotated classes first then process their inner annotations. This is performed at compile time and I will have no existing knowledge of the class being processed. It is possible to have multiple nested classes within Foo. How do I process the annotations of all these nested classes.

@MyAnnotation(value="Something important")
public class Foo
{
    private Integer A;

    @MyMethodAnnotation(value="Something Else")
    public Integer getA() { return this.A; }

    @MyAnnotation(value="Something really important")
    private class Bar
    {
        private Integer B;

        @MyMethodAnnotation(value="Something Else that is very Important")
        public Integer getB() { return this.B }     
    }
}

How can I get access to the nested Bar class, it's annotation 'MyAnnotation' and its 'MyMethodAnnotation' during processing? The following code only prints out information about class Foo. How can I process information about Bar?

for (Element element : env.getElementsAnnotatedWith(MyAnnotation.class)) {
    if ( element.getKind().equals(ElementKind.CLASS) )
    {
        System.out.println(element.getKind().name() + " " + element.getSimpleName() );
        processInnerClassElement(element);
    }
    else
    {
        System.out.println(element.getKind().name() + " " + element.getSimpleName() );
    }    
}

...


private void processInnerClassElement(Element element)
{
    for (Element e : element.getEnclosedElements() )
    {
        if ( e.getKind().equals(ElementKind.CLASS) )
        {
            System.out.println(e.getKind().name() + " " + e.getSimpleName() );
            processInnerClassElement(e);
        }
        else
        {
            System.out.println(e.getKind().name() + " " + e.getSimpleName()  );
        }
    }
}
1
  • I try accessing an element on the nested class Bar using for ( Element e : env.getElementsAnnotatedWith(EmfInfo.class) ) { but this only returns the outer most class Foo. Commented Oct 16, 2012 at 14:41

2 Answers 2

1

I guess it depends how these annotation relate to each other.

You could simply declare all the annotations in @SupportedAnnotationTypes and have several blocks in the process-method like:

for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {
    MyAnnotation myAnnotation = element.getAnnotation(MyAnnotation.class);
    if (myAnnotation != null) {
        doSomething(myAnnotation, element);
    }
}

for (Element element : roundEnv.getElementsAnnotatedWith(MyMethodAnnotation.class)) {
    MyMethodAnnotation myMethodAnnotation = element.getAnnotation(MyMethodAnnotation.class);
    if (myMethodAnnotation != null) {
        doSomething(myMethodAnnotation, element);
    }
}

Otherwise you might be able to use element.getEnclosedElements() and element.getEnclosingElement() to achieve what you want.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked perfectly. I actually had a problem in my source that was causing me errors. With that corrected the solution above processed the annotations of the nested class.
-1

You'll need a few methods from Class and Method to do this, specifically to get the classes declared in Foo, the annotations on those classes, the methods declared in those classes, and the annotations on those methods. Here is a quick example:

public static void main(String... args) {
    for (Class<?> declaredClass : Foo.class.getDeclaredClasses()) {
        MyAnnotation myAnnotation = declaredClass.getAnnotation(MyAnnotation.class);
        // Process value of class annotation here
        for (Method method : declaredClass.getDeclaredMethods()) {
            MyMethodAnnotation myMethodAnnotation = method.getAnnotation(MyMethodAnnotation.class);
            // Process value of method annotation here
        }
    }
}

It might be insightful to read through the documentation about reflection in Java: http://docs.oracle.com/javase/tutorial/reflect/index.html

2 Comments

You are speaking about reflection API. OP asked about annotation processor. It is not reflection. It is other API that is a kind of extension to java compiler.
I am using the Annotation Processing Tool an extension of the complier in Java6. I do not know the nested class names while I am processing files using the Annotation Processing Tool at compile time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.