2012-08-02 19 views
2

我在編譯時使用APT處理註釋,我需要在某些類中獲取@XmlElement註釋的值。這個類看起來是這樣的:如何訪問APT中的@XmlElement值?

public class ComponentConfig { 

    @XmlElements({ 
     @XmlElement(type = Sample1.class, name = "sample-1-config"), 
     @XmlElement(type = Sample2.class, name = "sample-2-config"), 
     @XmlElement(type = Sample3.class, name = "sample-3-config"), 
    }) 

    //... 
} 

我想獲得@XmlElementname值,但下面的處理器代碼不能把它拿來給我:

List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors(); 
for (AnnotationMirror mirror : annotationMirrors) { 
    if (mirror.getAnnotationType().toString().equals(XML_ELEMENT)) { 
     System.out.println(getAnnotationValueMapValueOfName(mirror)); 
     nodes.add(getAnnotationValueMapValueOfName(mirror)); 
    } 
} 

回答

1

所以它不容易,但它與JDK6 +的AbstractProcessor作品:

@Override 
public boolean process(final Set<? extends TypeElement> annotations, 
     final RoundEnvironment roundEnv) { 
    checkEnvironmentChange(); 
    System.out.println(" > ---- process2 method starts " + hashCode()); 
    System.out.println(" > annotations: " + annotations); 

    for (final TypeElement annotation: annotations) { 
     System.out.println(" > annotation: " + annotation.toString()); 
     processAnnotation(roundEnv, annotation); 
    } 
    System.out.println(" > processingOver: " + roundEnv.processingOver()); 
    System.out.println(" > ---- process2 method ends " + hashCode()); 
    return false; 
} 

private void processAnnotation(final RoundEnvironment roundEnv, 
     final TypeElement annotation) { 
    final Set<? extends Element> annotateds = 
      roundEnv.getElementsAnnotatedWith(annotation); 
    for (final Element element: annotateds) { 
     processElement(element); 
    } 
} 

private void processElement(final Element element) { 
    System.out.println("  > class: " + element); 
    System.out.println("  > class2: " + element.getClass()); 
    final List<? extends Element> enclosedElements = 
      element.getEnclosedElements(); 
    for (final Element enclosedElement: enclosedElements) { 
     processEnclosedElement(enclosedElement); 
    } 
} 

private void processEnclosedElement(final Element enclosedElement) { 
    final XmlElements xmlElements = 
      enclosedElement.getAnnotation(XmlElements.class); 
    if (xmlElements == null) { 
     return; 
    } 
    final XmlElement[] xmlElemntValues = xmlElements.value(); 
    for (final XmlElement xmlElementValue: xmlElemntValues) { 
     System.out.println("   > name: " + xmlElementValue.name()); 
    } 
} 

輸出:

[...] 
    > annotations: [hu.palacsint.annotation.MyAnnotation] 
    > annotation: hu.palacsint.annotation.MyAnnotation 
     > class: hu.palacsint.annotation.p2.ClassTwo 
     > class2: class com.sun.tools.javac.code.Symbol$ClassSymbol 
      > name: sample-1-config 
      > name: sample-2-config 
      > name: sample-3-config 
    > processingOver: false 
[...] 

我的前一個問題也可以幫助:Processing different annotations with the same Processor instance

1

哪裏是XML_ELEMENT定義?它至少應該是一個完全合格的名稱。使用getAnnotationType().toString()不是做比較的好基礎。

如果您打印出您找到的所有getAnnotationType().toString()的值,可能會發現您的問題。

也應該使用javax.annotation.processing軟件包,因爲APT現在已被棄用(因爲它最近已從構建中移除以用於即將到來的JDK8-IIRC)。它有點更好用,並且受到所有JDK6 +實現的支持。

+0

+1,好知道APT已被棄用。我剛剛找到關於它的博客條目:https://blogs.oracle.com/darcy/entry/apt_ending – palacsint 2012-08-09 22:16:26