Question

I'm processing annotations with APT in compile time, and I need to get the values of @XmlElement annotations in some classes. The class looks something like this:

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"),
    })

    //...
}

I'd like to get the name value of the @XmlElement, but the following processor code cannot fetch it for me:

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));
    }
}
Was it helpful?

Solution

It's not APT, but it works with the AbstractProcessor of JDK6+:

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

Output:

[...]
   > 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
[...]

My former question also could help: Processing different annotations with the same Processor instance

OTHER TIPS

Where is XML_ELEMENT defined? It should at least be a fully qualified name.

Using getAnnotationType().toString() is not a good basis to do the comparison.

If you printed out the values of all getAnnotationType().toString() that you find, you might spot your problem.

Also should be using javax.annotation.processing package as APT is now deprecated (as it has recently been removed from the build for the upcoming JDK8 - IIRC). It is a bit nicer to use, and supported by all JDK6+ implementations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top