You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2011/04/30 00:56:21 UTC

svn commit: r1098007 - in /tapestry/tapestry5/trunk/plastic/src: main/java/org/apache/tapestry5/internal/plastic/ test/groovy/org/apache/tapestry5/plastic/ test/java/testannotations/ test/java/testsubjects/

Author: hlship
Date: Fri Apr 29 22:56:20 2011
New Revision: 1098007

URL: http://svn.apache.org/viewvc?rev=1098007&view=rev
Log:
TAP5-853: Take @Inherited into account when searching for annotations on a PlasticClass

Added:
    tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/DelegatingAnnotationAccess.java
    tapestry/tapestry5/trunk/plastic/src/test/java/testannotations/InheritedAnnotation.java
    tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationBaseClass.java
    tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationSubClass.java
Modified:
    tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
    tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java
    tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ClassAnnotationAccess.groovy

Added: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/DelegatingAnnotationAccess.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/DelegatingAnnotationAccess.java?rev=1098007&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/DelegatingAnnotationAccess.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/DelegatingAnnotationAccess.java Fri Apr 29 22:56:20 2011
@@ -0,0 +1,47 @@
+package org.apache.tapestry5.internal.plastic;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Inherited;
+
+import org.apache.tapestry5.plastic.AnnotationAccess;
+
+/**
+ * Delegating annotation access is used when resolving annotations on a class; it searches the primary
+ * annotation access and if not found there (and {@link Inherited} is on the annotation being searched),
+ * it searches in the inherited access.
+ */
+public class DelegatingAnnotationAccess implements AnnotationAccess
+{
+    private final AnnotationAccess primary;
+
+    private final AnnotationAccess inherited;
+
+    public DelegatingAnnotationAccess(AnnotationAccess primary, AnnotationAccess inherited)
+    {
+        this.primary = primary;
+        this.inherited = inherited;
+    }
+
+    private boolean isInherited(Class<? extends Annotation> annotationType)
+    {
+        return annotationType.getAnnotation(Inherited.class) != null;
+    }
+
+    public <T extends Annotation> boolean hasAnnotation(Class<T> annotationType)
+    {
+        if (primary.hasAnnotation(annotationType))
+            return true;
+
+        return isInherited(annotationType) && inherited.hasAnnotation(annotationType);
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+    {
+        T fromPrimary = primary.getAnnotation(annotationType);
+
+        if (fromPrimary != null)
+            return fromPrimary;
+
+        return isInherited(annotationType) ? inherited.getAnnotation(annotationType) : null;
+    }
+}

Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java?rev=1098007&r1=1098006&r2=1098007&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java Fri Apr 29 22:56:20 2011
@@ -1482,11 +1482,12 @@ public class PlasticClassImpl extends Lo
 
         staticContext = parentStaticContext.dupe();
 
-        annotationAccess = pool.createAnnotationAccess(classNode.visibleAnnotations);
-
         className = PlasticInternalUtils.toClassName(classNode.name);
         superClassName = PlasticInternalUtils.toClassName(classNode.superName);
 
+        annotationAccess = new DelegatingAnnotationAccess(pool.createAnnotationAccess(classNode.visibleAnnotations),
+                pool.createAnnotationAccess(superClassName));
+
         this.parentMethodBundle = parentMethodBundle;
         methodBundle = parentMethodBundle.createChild(className);
 

Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java?rev=1098007&r1=1098006&r2=1098007&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassPool.java Fri Apr 29 22:56:20 2011
@@ -135,6 +135,33 @@ public class PlasticClassPool implements
         return writer.toByteArray();
     }
 
+    public AnnotationAccess createAnnotationAccess(String className)
+    {
+        try
+        {
+            final Class searchClass = loader.loadClass(className);
+
+            return new AnnotationAccess()
+            {
+                public <T extends Annotation> boolean hasAnnotation(Class<T> annotationType)
+                {
+                    return getAnnotation(annotationType) != null;
+                }
+
+                public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+                {
+                    // For the life of me, I don't understand why the cast is necessary.
+
+                    return annotationType.cast(searchClass.getAnnotation(annotationType));
+                }
+            };
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
     public AnnotationAccess createAnnotationAccess(List<AnnotationNode> annotationNodes)
     {
         if (annotationNodes == null)

Modified: tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ClassAnnotationAccess.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ClassAnnotationAccess.groovy?rev=1098007&r1=1098006&r2=1098007&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ClassAnnotationAccess.groovy (original)
+++ tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ClassAnnotationAccess.groovy Fri Apr 29 22:56:20 2011
@@ -3,31 +3,39 @@ package org.apache.tapestry5.plastic
 import org.apache.tapestry5.plastic.PlasticManager;
 
 import spock.lang.Specification;
+import testannotations.InheritedAnnotation;
 import testannotations.SimpleAnnotation;
 
 class ClassAnnotationAccess extends Specification {
     def mgr = new PlasticManager()
     def pc = mgr.getPlasticClass("testsubjects.AnnotationSubject")
-    
+
     def "access to non-existent annotation"() {
-        
+
         expect:
-        
+
         pc.hasAnnotation(Deprecated.class) == false
         pc.getAnnotation(Deprecated.class) == null
     }
-    
+
     def "check existence of known, simple annotation"() {
-        
+
         expect:
         pc.hasAnnotation(SimpleAnnotation.class) == true
-        
+
         when:
         def a = pc.getAnnotation(SimpleAnnotation.class)
-        
+
         then:
         a instanceof SimpleAnnotation
-        
+
         a.annotationType() == SimpleAnnotation.class
     }
+
+    def "inherited class annotations visible in subclass"() {
+        def pc = mgr.getPlasticClass("testsubjects.InheritedAnnotationSubClass")
+
+        expect:
+        pc.hasAnnotation(InheritedAnnotation.class) == true
+    }
 }

Added: tapestry/tapestry5/trunk/plastic/src/test/java/testannotations/InheritedAnnotation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/java/testannotations/InheritedAnnotation.java?rev=1098007&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/java/testannotations/InheritedAnnotation.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/test/java/testannotations/InheritedAnnotation.java Fri Apr 29 22:56:20 2011
@@ -0,0 +1,20 @@
+package testannotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(
+{ TYPE, FIELD, METHOD, PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface InheritedAnnotation
+{
+
+}

Added: tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationBaseClass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationBaseClass.java?rev=1098007&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationBaseClass.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationBaseClass.java Fri Apr 29 22:56:20 2011
@@ -0,0 +1,9 @@
+package testsubjects;
+
+import testannotations.InheritedAnnotation;
+
+@InheritedAnnotation
+public class InheritedAnnotationBaseClass
+{
+
+}

Added: tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationSubClass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationSubClass.java?rev=1098007&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationSubClass.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/InheritedAnnotationSubClass.java Fri Apr 29 22:56:20 2011
@@ -0,0 +1,6 @@
+package testsubjects;
+
+public class InheritedAnnotationSubClass extends InheritedAnnotationBaseClass
+{
+
+}