2012-10-11 10 views
6

Sto provando a scrivere un processore di annotazione utilizzando java. Questo elaboratore di annotazioni deve identificare classi annidate annotate all'interno di una classe annotata come mostrato di seguito. Elaborerò prima le classi annotate e poi elaborerò le loro annotazioni interne. Questo viene eseguito in fase di compilazione e non avrò alcuna conoscenza della classe in elaborazione. È possibile avere più classi annidate all'interno di Foo. Come posso elaborare le annotazioni di tutte queste classi annidate.APT Come elaborare annotazioni di classi annotate nidificate

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

Come posso ottenere l'accesso alla classe Bar nidificato, è l'annotazione 'MyAnnotation' e il suo 'MyMethodAnnotation' durante la lavorazione? Il seguente codice stampa solo informazioni sulla classe Foo. Come posso elaborare le informazioni su 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

provo si accede a un elemento della classe Bar nidificato utilizzando per (Element e: env.getElementsAnnotatedWith (EmfInfo.class)) { ma questo restituisce solo l'esterno più classe Foo. – sholmes

risposta

0

Immagino che dipende da come queste annotazioni in relazione tra loro.

Si potrebbe semplicemente dichiarare tutte le annotazioni in @SupportedAnnotationTypes e hanno diversi isolati nel processo-metodo come:

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

In caso contrario si potrebbe essere in grado di utilizzare element.getEnclosedElements() e element.getEnclosingElement() per ottenere quello che vuoi.

+0

Questo ha funzionato perfettamente. In realtà ho avuto un problema nella mia fonte che mi stava causando errori. Con quella corretta la soluzione sopra elaborava le annotazioni della classe annidata. – sholmes

-1

Avrete bisogno di un paio di metodi da Class e Method per fare questo, in particolare per ottenere le classi dichiarate nelle Foo, le annotazioni su quelle classi, i metodi dichiarati in quelle classi e le annotazioni su questi metodi . Ecco un rapido esempio:

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

Potrebbe essere penetranti di leggere la documentazione relativa riflessione in Java: http://docs.oracle.com/javase/tutorial/reflect/index.html

+3

Stai parlando dell'API di reflection. OP ha chiesto informazioni sul processore di annotazione. Non è una riflessione. È un'altra API che è una specie di estensione del compilatore java. – AlexR

+0

Sto usando lo strumento di elaborazione annotazioni un'estensione del compilatore in Java6. Non conosco i nomi di classe nidificati mentre sto elaborando i file utilizzando lo strumento di elaborazione delle annotazioni in fase di compilazione. – sholmes