Using Groovy AST to Add Common Properties to Grails Domain Classes
Groovy offers a lot of runtime meta-programming capabilities that allow you to add reusable functionality in a shared fashion. Grails plugins make use of this ability to enhance your project. One of the things that you can't do with runtime meta-programming in Grails is to add persistent Hibernate properties to your domain classes. If you want to add a persistent property in a plugin (or otherwise using meta-programming) for your Grails project you have to make use of "compile-time" meta-programming. In Groovy this is done with AST Transformations.
AST Transformations are made up of two parts: (1) An annotation and (2) an ASTTransformation implementation. During compilation the Groovy compiler finds all of the Annotations and calls the ASTTransformation implementation for the annotation passing in information about.
To create your own Transformation you start by creating an Annotation. The key to the annotation working is that your annotation has to itself be annotated with @GroovyASTTransformationClass. The values passed to the GroovyASTTransformationClass define the Transformation that will be called on classes, methods or other code prior to it being compiled.
Example Annotation
Notice the reference to net.zorched.grails.effectivity.EffectivizeASTTransformation. That's the important part because it defines the class that will be used to perform the transformation.
Example Transformation
This example code gets called for each annotated class and adds two new Date properties called effectiveStart and effectiveEnd to it. Those properties are seen by Grails and Hibernate and will become persistent and behave the same as if you typed them directly in your Domain.
It's a lot of work to add a simple property to a class, but if you're looking to consistently add properties and constraints across many Grails Domain classes, this is the way to do it.