Nico
Nico

Reputation: 1803

Annotation processing unknown Annotation

currently I am writing an Annotation processor, which will generate new source code. This Processor is isolated from the application itself, as it is a step in building the project and I seperated the whole buildsystem from the application.

This is where the problem starts, because I want to process an Annotation that is created in the application. Let's name it CustomAnnotation. with the fully qualified name com.company.api.annotation.CustomAnnotation.

In the processor I can search for annotations by the fully qualified name, what's really nice. Now I seem to be able to get the Methods, field etc that are annotated since I can call the function getElementsAnnotatedWith with TypeElement instead of Class.

Now our CustomAnnotation has fields and variables in it and normally I would get the Annotation itself like this: Class annotation = Element.getAnnotation(Class) But I can't use this since CustomAnnotation is not available as Class Object.(sure, it's not known to the processor) I tried using TypeMirror and other available things but nothing seems to work.

Does anybody know a way to get the Annotation to read it's values?

EDIT: Let's look at this implementation:

@SupportedAnnotationTypes( "com.company.api.annotation.CustomAnnotation" )
@SupportedSourceVersion( SourceVersion.RELEASE_8 )  
public class CustomProcessor extends AbstractProcessor
{

  public CustomProcessor()
  {
    super();
  }

  @Override
  public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv )
  {
    TypeElement test = annotations.iterator().next();

    for ( Element elem : roundEnv.getElementsAnnotatedWith( test ) )
    {
      //Here is where I would get the Annotation element itself to 
      //read the content of it if I can use the Annotation as Class Object. 
      SupportedAnnotationTypes generated = elem.getAnnotation( SupportedAnnotationTypes.class );
    }
 }

However I don't have to use CustomAnnotation.class since it doesn't exist in this environment. How can I do this without owning the Class object?

Upvotes: 4

Views: 1095

Answers (1)

Holger
Holger

Reputation: 298233

You can query the annotations as AnnotationMirror which does not require the annotation type to be a loaded runtime Class:

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    for(TypeElement test: annotations) {
        for( Element elem : roundEnv.getElementsAnnotatedWith( test ) ) {
            System.out.println(elem);
            for(AnnotationMirror am: elem.getAnnotationMirrors()) {
                if(am.getAnnotationType().asElement()==test)
                    am.getElementValues().forEach((ee,av) ->
                        System.out.println("\t"+ee.getSimpleName()+" = "+av.getValue())
                    );
            }
        }
    }
    return true;
}

Upvotes: 3

Related Questions