2012-10-11 32 views
6

Estoy intentando escribir un procesador de anotaciones usando java. Este procesador de anotación necesita identificar clases anotadas anotadas dentro de una clase anotada como se ve a continuación. Procesaré las clases anotadas primero y luego procesaré sus anotaciones internas. Esto se realiza en tiempo de compilación y no tendré conocimiento de la clase que se está procesando. Es posible tener múltiples clases anidadas dentro de Foo. ¿Cómo se procesan las anotaciones de todas estas clases anidadas?APT Cómo procesar anotaciones de clases anotadas anidadas

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

¿Cómo puedo obtener acceso a la clase anidada bar, que es la anotación 'MyAnnotation' y su 'MyMethodAnnotation' durante el proceso? El siguiente código solo imprime información sobre la clase Foo. ¿Cómo puedo procesar información sobre 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() ); 
     } 
    } 
} 
+0

que intente acceder a un elemento de la barra de clase anidada usando para (elemento E: env.getElementsAnnotatedWith (EmfInfo.class)) { pero esto sólo se devuelve el exterior Foo más clase. – sholmes

Respuesta

0

Supongo que depende de cómo estas anotaciones se relacionan entre sí.

Simplemente podría declarar todas las anotaciones en @SupportedAnnotationTypes y tienen varios bloques en el proceso de método como:

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

De lo contrario, podría ser capaz de utilizar element.getEnclosedElements() y element.getEnclosingElement() para lograr lo que quiere.

+0

Esto funcionó perfectamente. De hecho, tuve un problema en mi fuente que me estaba causando errores. Una vez corregida, la solución anterior procesa las anotaciones de la clase anidada. – sholmes

-1

Tendrá que algunos métodos de Class y Method a ello, en concreto para conseguir las clases declaradas en Foo, las anotaciones en esas clases, los métodos declarados en esas clases, y las anotaciones en los métodos . Aquí está un ejemplo rápido:

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

Podría ser perspicaz para leer a través de la documentación sobre la reflexión en Java: http://docs.oracle.com/javase/tutorial/reflect/index.html

+3

Usted está hablando de la API de reflexión. OP preguntó sobre el procesador de anotación. No es reflejo. Es otra API que es una especie de extensión para el compilador de Java. – AlexR

+0

Estoy usando la Herramienta de procesamiento de anotaciones como una extensión del compilador en Java6. No conozco los nombres de clase anidados mientras estoy procesando archivos usando la herramienta de procesamiento de anotaciones en tiempo de compilación. – sholmes

Cuestiones relacionadas