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
+{
+
+}