Hi Cédric!
Thank you for your hint.
My example was oversimplified, sorry: I put the annotation on an import
statement and on the package declaration (in two different tests), but both
s.getClass().getAnnotations()
and
s.getClass().getPackage().getAnnotations()
were empty.
So I tried implementing an ASTTransform that puts my annotation on
ClassNode: contrary to my belief, it was simple and now I can find the
annotation on the class.
These are the correct examples and the ASTTransformation:
--- CustomAnnotation.java ---
package xxxx;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.codehaus.groovy.transform.GroovyASTTransformationClass;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD,
ElementType.TYPE,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.LOCAL_VARIABLE,
ElementType.PACKAGE
})
@GroovyASTTransformationClass("xxxx.CustomAnnotationASTTransformation")
public @interface CustomAnnotation {
String value() default "";
String description() default "";
}
--- END ---
--- CustomAnnotationASTTransformation.java ---
package xxxx;
import java.util.List;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.AbstractASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;
@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class CustomAnnotationASTTransformation extends
AbstractASTTransformation {
static final Class<?> MY_CLASS = CustomAnnotation.class;
static final ClassNode MY_TYPE = ClassHelper.make(MY_CLASS);
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotationNode anno = (AnnotationNode) nodes[0];
if (!MY_TYPE.equals(anno.getClassNode()))
return;
ClassNode scriptClass = source.getAST().getClasses().get(0);
List<AnnotationNode> annos =
scriptClass.getAnnotations(anno.getClassNode());
if (annos.isEmpty()) {
scriptClass.addAnnotation(anno);
}
}
}
--- END ---
--- script1.groovy ---
package xxxx
@CustomAnnotation("xyz")
import xxxx.CustomAnnotation;
println "Hello world!"
--- END ---
--- script2.groovy ---
@CustomAnnotation("xyz")
package xxxx
import xxxx.CustomAnnotation;
class XYZ {}
println "Hello world!"
--- END ---
Now both script1 and script2 have one annotation at class level.
Stefano
--
-----------------------------------------
Ing. Stefano Rocca
e-mail: s.ro...@oandsi.it
O.&.S.I. Srl
Outsourcing & Sistemi Informativi
via Goldoni, 27
20023 Cerro Maggiore (MI) - Italy
Tel. +39 0331 421787 Fax. +39 0331 511238