2013-01-24 76 views
7

我试图动态地创建一个注解,它将动态地向使用元编程和AST的类中的每个字段添加@XmlElement注释。我在创建注释并将它们正确应用于字段时遇到了问题。Groovy AST-在编译时添加注释

的代码,我在这里格式:http://pastebin.com/60DTX5Ya

import javax.xml.bind.annotation.XmlElement 

@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) 
class WebserviceAnnotationModifier implements ASTTransformation { 
@Override 
void visit(ASTNode[] astNodes, SourceUnit sourceUnit) { 

    if (!astNodes) return 
    if (!astNodes[0] || !astNodes[1]) return 
    if (!(astNodes[0] instanceof AnnotationNode)) return 
    if (!(astNodes[1] instanceof ClassNode)) return 
    ClassNode node = (ClassNode)astNodes[1] 
    List fields = node.getFields() 
    fields.each {FieldNode field -> 
     field.addAnnotation(ClassHelper.make(new XmlElement.DEFAULT())); 
    } 
} 
} 

@Retention(RetentionPolicy.SOURCE) 
@Target([ElementType.TYPE]) 
@GroovyASTTransformationClass(classes =[WebserviceAnnotationModifier]) 
public @interface WebresourceAnnotation{} 

@WebresourceAnnotation 
class TestPerson{ 
    String name; 
    String lastName; 
    int Age 
} 

我是接近这一切都错了吗?我这样做的原因是我有一个域仍在制作中,我想进入并将注释应用于所有字段。找不到在编译过程中添加的任何注释示例。这不可能吗?

+0

你是说你将注释应用到域。它是Grails域的类吗?我的意思是你要在Grails环境中使用你的注释吗? – chanwit

+0

是的,我将使用一些JAXB XML注释来生成SOAP服务。我想要的是让WebresourceAnnotation注释将通过域对象中的每个字段并添加一个普通的XmlElement注释。 – Elotin

回答

1

单独使用Groovy AST Transformation编写代码不适用于Grails重载机制。这是一个为Grails应用程序实现AST转换的正确方法。

  1. 您的变压器类别必须延伸AbstractGrailsArtefactTransformer
  2. 您的变压器类别必须注明@AstTransformer
  3. 您的课程必须置于org.codehaus.groovy.grails.compiler或其子包装内。在我的情况下,我使用org.codehaus.groovy.grails.compiler.zk,它工作正常。
  4. 执行shouldInject()只匹配你想要的类,在这种情况下是域类。
  5. 覆盖performInjection()并在那里写你的代码。
  6. 你的变压器和相关类到.jar文件,或Grails编译器不加载它。
+0

非常感谢。我会看看它,看看我能弄清楚什么。我陷入了不确定如何实际创建一个AnnotationNode。 – Elotin

+0

没问题。不要忘记接受它作为你的变压器工作后的答案:) – chanwit