2012-10-11 4 views
6

Ich versuche, einen Annotationsprozessor mit Java zu schreiben. Dieser Annotationsprozessor muss annotierte verschachtelte Klassen in einer annotierten Klasse identifizieren (siehe unten). Ich werde die annotierten Klassen zuerst bearbeiten und dann ihre inneren Anmerkungen verarbeiten. Dies wird zur Kompilierzeit durchgeführt, und ich werde keine Kenntnis von der Klasse haben, die gerade verarbeitet wird. Es ist möglich, mehrere geschachtelte Klassen innerhalb von Foo zu haben. Wie verarbeite ich die Annotationen aller dieser verschachtelten Klassen.APT Wie man Anmerkungen von verschachtelten annotierten Klassen verarbeitet

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

Wie kann ich Zugriff auf die verschachtelten Bar Klasse erhalten, ist es Vermerk ‚MyAnnotation‘ und seine ‚MyMethodAnnotation‘ während der Verarbeitung? Der folgende Code gibt nur Informationen über die Klasse Foo aus. Wie kann ich Informationen über die Bar verarbeiten?

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

Ich versuche den Zugriff auf ein Element auf der Bar verschachtelten Klasse für (Element e: env.getElementsAnnotatedWith (EmfInfo.class)) unter Verwendung { aber dies gibt nur die äußersten Klasse Foo. – sholmes

Antwort

0

Ich denke, es hängt davon ab, wie diese Anmerkung zueinander in Beziehung steht.

Sie könnten einfach alle Anmerkungen in @SupportedAnnotationTypes erklären und haben mehrere Blöcke in dem Prozess-Verfahren wie:

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

Andernfalls könnte der Lage sein, Sie element.getEnclosedElements() und element.getEnclosingElement() zu verwenden, um zu erreichen, was Sie wollen.

+0

Das hat perfekt funktioniert. Ich hatte tatsächlich ein Problem in meiner Quelle, das mir Fehler verursachte. Damit hat die obige Lösung die Annotationen der geschachtelten Klasse korrigiert. – sholmes

-1

Sie werden von Class und Method ein paar Methoden benötigen, dies zu tun, insbesondere die Klassen in Foo, die Anmerkungen zu diesen Klassen erklärt zu bekommen, die in diesen Klassen deklarierten Methoden, und die Anmerkungen zu diesen Methoden . Hier ist ein kurzes Beispiel:

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

Es könnte sein, einsichtig durch die Dokumentation über Reflexion in Java zu lesen: http://docs.oracle.com/javase/tutorial/reflect/index.html

+3

Sie sprechen über Reflection API. OP fragte nach Annotationsprozessor. Es ist keine Reflexion. Es ist eine andere API, die eine Art Erweiterung des Java-Compilers ist. – AlexR

+0

Ich verwende das Annotation Processing Tool eine Erweiterung des Compliers in Java6. Ich kenne die verschachtelten Klassennamen nicht, während ich Dateien mit dem Annotation Processing Tool zur Kompilierzeit verarbeite. – sholmes

Verwandte Themen