@groovy.transform.CompileStatic @org.codehaus.groovy.transform.GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) class TransactionalTransform extends AbstractDatastoreMethodDecoratingTransformation
This AST transform reads the Transactional annotation and transforms method calls by wrapping the body of the method in an execution of GrailsTransactionTemplate.
In other words given the following class:
class FooService {
@Transactional
void updateFoo() {
...
}
}
The resulting byte code produced will be (more or less):
class FooService { PlatformTransactionManager $transactionManager PlatformTransactionManager getTransactionManager() { $transactionManager } void updateFoo() { GrailsTransactionTemplate template = new GrailsTransactionTemplate(getTransactionManager()) template.execute { TransactionStatus status -> $tt_updateFoo(status) } } private void $tt_updateFoo(TransactionStatus status) { ... } }
The body of the method is moved to a new method prefixed with "$tt_" and which receives the arguments of the method and the TransactionStatus object
Modifiers | Name | Description |
---|---|---|
static java.lang.String |
GET_TRANSACTION_MANAGER_METHOD |
|
static org.codehaus.groovy.ast.ClassNode |
MY_TYPE |
|
static int |
POSITION |
The position of the transform in terms ordering |
static org.codehaus.groovy.ast.ClassNode |
READ_ONLY_TYPE |
|
static java.lang.String |
RENAMED_METHOD_PREFIX |
Fields inherited from class | Fields |
---|---|
class AbstractDatastoreMethodDecoratingTransformation |
FIELD_TARGET_DATASTORE, METHOD_GET_DATASTORE_FOR_CONNECTION, METHOD_GET_TARGET_DATASTORE |
class AbstractMethodDecoratingTransformation |
DECORATED_METHODS |
class org.codehaus.groovy.transform.AbstractASTTransformation |
RETENTION_CLASSNODE, ASM4, ASM5, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER, ACC_SYNCHRONIZED, ACC_VOLATILE, ACC_BRIDGE, ACC_VARARGS, ACC_TRANSIENT, ACC_NATIVE, ACC_INTERFACE, ACC_ABSTRACT, ACC_STRICT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MANDATED, ACC_DEPRECATED, T_BOOLEAN, T_CHAR, T_FLOAT, T_DOUBLE, T_BYTE, T_SHORT, T_INT, T_LONG, H_GETFIELD, H_GETSTATIC, H_PUTFIELD, H_PUTSTATIC, H_INVOKEVIRTUAL, H_INVOKESTATIC, H_INVOKESPECIAL, H_NEWINVOKESPECIAL, H_INVOKEINTERFACE, F_NEW, F_FULL, F_APPEND, F_CHOP, F_SAME, F_SAME1, TOP, INTEGER, FLOAT, DOUBLE, LONG, NULL, UNINITIALIZED_THIS, NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, BIPUSH, SIPUSH, LDC, ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, RET, TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, GETSTATIC, PUTSTATIC, GETFIELD, PUTFIELD, INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, INVOKEDYNAMIC, NEW, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST, INSTANCEOF, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, IFNULL, IFNONNULL |
Type Params | Return Type | Name and description |
---|---|---|
|
protected java.lang.Object |
applyTransactionalAttributeSettings(org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.expr.VariableExpression transactionAttributeVar, org.codehaus.groovy.ast.stmt.BlockStatement methodBody, org.codehaus.groovy.ast.ClassNode classNode, org.codehaus.groovy.ast.MethodNode methodNode) |
|
org.codehaus.groovy.ast.expr.MethodCallExpression |
buildDelegatingMethodCall(org.codehaus.groovy.control.SourceUnit sourceUnit, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode classNode, org.codehaus.groovy.ast.MethodNode methodNode, org.codehaus.groovy.ast.expr.MethodCallExpression originalMethodCall, org.codehaus.groovy.ast.stmt.BlockStatement newMethodBody) |
|
protected void |
enhanceClassNode(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode declaringClassNode) |
|
static org.codehaus.groovy.ast.AnnotationNode |
findTransactionalAnnotation(org.codehaus.groovy.ast.MethodNode methodNode) Finds the transactional annotation for the given method node |
|
protected org.codehaus.groovy.ast.ClassNode |
getAnnotationType() |
|
protected java.lang.Object |
getAppliedMarker() |
|
int |
getOrder() |
|
protected java.lang.String |
getRenamedMethodPrefix() |
|
protected java.lang.String |
getTransactionTemplateMethodName() |
|
protected boolean |
hasExcludedAnnotation(org.codehaus.groovy.ast.MethodNode md) |
|
static boolean |
hasTransactionalAnnotation(org.codehaus.groovy.ast.AnnotatedNode md) Whether the given method has a transactional annotation |
|
protected boolean |
isValidAnnotation(org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.AnnotatedNode classNode) |
|
protected org.codehaus.groovy.ast.Parameter[] |
prepareNewMethodParameters(org.codehaus.groovy.ast.MethodNode methodNode, java.util.Map<java.lang.String, org.codehaus.groovy.ast.ClassNode> genericsSpec, org.codehaus.groovy.ast.ClassNode classNode = null) |
|
protected void |
weaveClassNode(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode classNode) |
|
protected org.codehaus.groovy.ast.MethodNode |
weaveNewMethod(org.codehaus.groovy.control.SourceUnit sourceUnit, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode classNode, org.codehaus.groovy.ast.MethodNode methodNode, java.util.Map<java.lang.String, org.codehaus.groovy.ast.ClassNode> genericsSpec) |
|
protected void |
weaveSetTargetDatastoreBody(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode declaringClassNode, org.codehaus.groovy.ast.expr.Expression datastoreVar, org.codehaus.groovy.ast.stmt.BlockStatement setTargetDatastoreBody) |
|
protected void |
weaveTestSetupMethod(org.codehaus.groovy.control.SourceUnit sourceUnit, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode classNode, org.codehaus.groovy.ast.MethodNode methodNode, java.util.Map<java.lang.String, org.codehaus.groovy.ast.ClassNode> genericsSpec) |
|
protected void |
weaveTransactionManagerAware(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.ast.AnnotationNode annotationNode, org.codehaus.groovy.ast.ClassNode declaringClassNode) |
Methods inherited from class | Name |
---|---|
class AbstractDatastoreMethodDecoratingTransformation |
enhanceClassNode, weaveSetTargetDatastoreBody |
class AbstractMethodDecoratingTransformation |
buildCallToOriginalMethod, buildDelegatingMethodCall, compileMethodStatically, createDelegingMethodBody, enhanceClassNode, getRenamedMethodPrefix, hasExcludedAnnotation, hasExcludedAnnotation, isTestSetupOrCleanup, makeDelegatingClosureCall, makeDelegatingClosureCall, moveOriginalCodeToNewMethod, prepareNewMethodParameters, resolveReturnTypeForNewMethod, visit, weaveClassNode, weaveNewMethod, weaveTestSetupMethod |
class AbstractGormASTTransformation |
getAnnotationType, getAppliedMarker, isValidAnnotation, visit, visit |
class org.codehaus.groovy.transform.AbstractASTTransformation |
org.codehaus.groovy.transform.AbstractASTTransformation#tokenize(java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#addError(java.lang.String, org.codehaus.groovy.ast.ASTNode), org.codehaus.groovy.transform.AbstractASTTransformation#nonGeneric(org.codehaus.groovy.ast.ClassNode), org.codehaus.groovy.transform.AbstractASTTransformation#memberHasValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String, java.lang.Object), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberList(org.codehaus.groovy.ast.AnnotationNode, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberStringValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberStringValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberIntValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberClassValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String, org.codehaus.groovy.ast.ClassNode), org.codehaus.groovy.transform.AbstractASTTransformation#getMemberClassValue(org.codehaus.groovy.ast.AnnotationNode, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#getClassList(org.codehaus.groovy.ast.AnnotationNode, java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#hasAnnotation(org.codehaus.groovy.ast.ClassNode, org.codehaus.groovy.ast.ClassNode), org.codehaus.groovy.transform.AbstractASTTransformation#deemedInternalName(java.lang.String), org.codehaus.groovy.transform.AbstractASTTransformation#shouldSkip(java.lang.String, java.util.List, java.util.List), org.codehaus.groovy.transform.AbstractASTTransformation#shouldSkipOnDescriptor(boolean, java.util.Map, org.codehaus.groovy.ast.MethodNode, java.util.List, java.util.List), org.codehaus.groovy.transform.AbstractASTTransformation#wait(long, int), org.codehaus.groovy.transform.AbstractASTTransformation#wait(long), org.codehaus.groovy.transform.AbstractASTTransformation#wait(), org.codehaus.groovy.transform.AbstractASTTransformation#equals(java.lang.Object), org.codehaus.groovy.transform.AbstractASTTransformation#toString(), org.codehaus.groovy.transform.AbstractASTTransformation#hashCode(), org.codehaus.groovy.transform.AbstractASTTransformation#getClass(), org.codehaus.groovy.transform.AbstractASTTransformation#notify(), org.codehaus.groovy.transform.AbstractASTTransformation#notifyAll(), org.codehaus.groovy.transform.AbstractASTTransformation#visit([Lorg.codehaus.groovy.ast.ASTNode;, org.codehaus.groovy.control.SourceUnit) |
The position of the transform in terms ordering
Finds the transactional annotation for the given method node
methodNode
- The method nodeWhether the given method has a transactional annotation
md
- The method node