Reputation: 1803
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
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