You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Stefano Rocca <s....@oandsi.it> on 2015/06/12 17:46:58 UTC

Annotation on script

Hi,
we're using groovy.util.GroovyScriptEngine to run our scripts and we 
would like to use reflection on the Script class returned by 
createScript to get the annotations declared in the script, for example:

--- script1.groovy ---
package xxxx

@CustomAnnotation("xyz", description = "aaa bbb ccc")

println "Hello world!"

--- END ---

--- 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;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({   ElementType.METHOD,         ElementType.TYPE,
             ElementType.CONSTRUCTOR,    ElementType.FIELD,
             ElementType.LOCAL_VARIABLE, ElementType.PACKAGE
})
public @interface CustomAnnotation {

     String value() default "";
     String description() default "";

}

--- END ---

if we execute

Script s = groovyScriptEngine.createScript("script1.groovy", new 
Binding()); // groovyScriptEngine is an instance of 
groovy.util.GroovyScriptEngine

we cannot find the annotation CustomAnnotation anywhere in Script s 
(i.e.: s.getClass().getAnnotations() is empty)

Is it possible to obtain such annotation?

Thanks in advance.

Stefano


Re: Annotation on script

Posted by Stefano Rocca <s....@oandsi.it>.
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.rocca@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


Re: Annotation on script

Posted by Cédric Champeau <ce...@gmail.com>.
Hi!

An annotation cannot be directly set on a script. Is has to be on a
package, import, ... So if in your example you use a package, then you
should annotate the package declaration and get the annotation from it.

2015-06-12 17:46 GMT+02:00 Stefano Rocca <s....@oandsi.it>:

> Hi,
> we're using groovy.util.GroovyScriptEngine to run our scripts and we would
> like to use reflection on the Script class returned by createScript to get
> the annotations declared in the script, for example:
>
> --- script1.groovy ---
> package xxxx
>
> @CustomAnnotation("xyz", description = "aaa bbb ccc")
>
> println "Hello world!"
>
> --- END ---
>
> --- 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;
>
> @Documented
> @Retention(RetentionPolicy.RUNTIME)
> @Target({   ElementType.METHOD,         ElementType.TYPE,
>             ElementType.CONSTRUCTOR,    ElementType.FIELD,
>             ElementType.LOCAL_VARIABLE, ElementType.PACKAGE
> })
> public @interface CustomAnnotation {
>
>     String value() default "";
>     String description() default "";
>
> }
>
> --- END ---
>
> if we execute
>
> Script s = groovyScriptEngine.createScript("script1.groovy", new
> Binding()); // groovyScriptEngine is an instance of
> groovy.util.GroovyScriptEngine
>
> we cannot find the annotation CustomAnnotation anywhere in Script s (i.e.:
> s.getClass().getAnnotations() is empty)
>
> Is it possible to obtain such annotation?
>
> Thanks in advance.
>
> Stefano
>
>