Permalink
Browse files

introduce grails.plugin.cache.CacheEvict

  • Loading branch information...
1 parent 3e29dc4 commit 3d92ef2320831a4f1784a9b03cbd7ae5832c2540 @jeffbrown jeffbrown committed Apr 30, 2012
@@ -1,7 +1,6 @@
package org.grails.plugin.cache
-import org.springframework.cache.annotation.CacheEvict
-
+import grails.plugin.cache.CacheEvict
class GrailsCacheAdminService {
@@ -0,0 +1,58 @@
+package grails.plugin.cache;
+
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+/**
+ * Annotation indicating that a method (or all methods on a class) trigger(s)
+ * a cache invalidate operation.
+ *
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@GroovyASTTransformationClass("grails.plugin.cache.compiler.CacheEvictTransformation")
+public @interface CacheEvict {
+
+ /**
+ * Qualifier value for the specified cached operation.
+ * <p>May be used to determine the target cache (or caches), matching the qualifier
+ * value (or the bean name(s)) of (a) specific bean definition.
+ */
+ String[] value();
+
+ /**
+ * Spring Expression Language (SpEL) attribute for computing the key dynamically.
+ * <p>Default is "", meaning all method parameters are considered as a key.
+ */
+ String key() default "";
+
+ /**
+ * Spring Expression Language (SpEL) attribute used for conditioning the method caching.
+ * <p>Default is "", meaning the method is always cached.
+ */
+ String condition() default "";
+
+ /**
+ * Whether or not all the entries inside the cache(s) are removed or not. By
+ * default, only the value under the associated key is removed.
+ * <p>Note that specifying setting this parameter to true and specifying a
+ * {@link CacheKey key} is not allowed.
+ */
+ boolean allEntries() default false;
+
+ /**
+ * Whether the eviction should occur after the method is successfully invoked (default)
+ * or before. The latter causes the eviction to occur irrespective of the method outcome (whether
+ * it threw an exception or not) while the former does not.
+ */
+ boolean beforeInvocation() default false;
+}
@@ -0,0 +1,38 @@
+package grails.plugin.cache.compiler;
+
+import java.util.Map;
+
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotatedNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.transform.ASTTransformation;
+import org.codehaus.groovy.transform.GroovyASTTransformation;
+
+
+@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
+public class CacheEvictTransformation implements ASTTransformation{
+
+ public void visit(final ASTNode[] astNodes, final SourceUnit sourceUnit) {
+
+ final ASTNode firstNode = astNodes[0];
+ final ASTNode secondNode = astNodes[1];
+ if (!(firstNode instanceof AnnotationNode) || !(secondNode instanceof AnnotatedNode)) {
+ throw new RuntimeException("Internal error: wrong types: " + firstNode.getClass().getName() + " / " + secondNode.getClass().getName());
+ }
+
+ final AnnotationNode grailsCachableAnnotationNode = (AnnotationNode) firstNode;
+ final AnnotatedNode parent = (AnnotatedNode) secondNode;
+ final Map<String, Expression> grailsAnnotationMembers = grailsCachableAnnotationNode.getMembers();
+
+ final AnnotationNode springCacheEvictAnnotationNode = new AnnotationNode(new ClassNode(org.springframework.cache.annotation.CacheEvict.class));
+ for(Map.Entry<String, Expression> entry : grailsAnnotationMembers.entrySet()) {
+ springCacheEvictAnnotationNode.addMember(entry.getKey(), entry.getValue());
+ }
+ parent.addAnnotation(springCacheEvictAnnotationNode);
+ }
+}
+

0 comments on commit 3d92ef2

Please sign in to comment.