You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by dr...@apache.org on 2010/11/15 07:28:58 UTC
svn commit: r1035155 - in /tapestry/tapestry5/trunk/tapestry-ioc/src:
main/java/org/apache/tapestry5/ioc/internal/services/ClassFabImpl.java
test/java/org/apache/tapestry5/ioc/internal/services/ClassFabImplTest.java
Author: drobiazko
Date: Mon Nov 15 06:28:58 2010
New Revision: 1035155
URL: http://svn.apache.org/viewvc?rev=1035155&view=rev
Log:
TAP5-1349: The method parameter annotations are missing from Tapestry IoC proxies
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFabImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ClassFabImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFabImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFabImpl.java?rev=1035155&r1=1035154&r2=1035155&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFabImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFabImpl.java Mon Nov 15 06:28:58 2010
@@ -22,6 +22,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Formatter;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -35,8 +36,10 @@ import javassist.bytecode.AnnotationsAtt
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.MethodInfo;
+import javassist.bytecode.ParameterAnnotationsAttribute;
import javassist.bytecode.annotation.MemberValue;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.services.ClassFab;
import org.apache.tapestry5.ioc.services.ClassFabUtils;
@@ -377,13 +380,15 @@ public class ClassFabImpl extends Abstra
assert method != null;
+ CtMethod ctMethod = getCtMethod(sig);
+
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations)
{
try
{
- addMethodAnnotation(getCtMethod(sig), annotation);
+ addMethodAnnotation(ctMethod, annotation);
}
catch (RuntimeException ex)
{
@@ -393,6 +398,18 @@ public class ClassFabImpl extends Abstra
annotation.annotationType(), method.getName(), delegateClass.getName()));
}
}
+
+ try
+ {
+ addMethodParameterAnnotation(ctMethod, method.getParameterAnnotations());
+ }
+ catch (RuntimeException ex)
+ {
+ //Annotation processing may cause exceptions thrown by Javassist.
+ //To provide backward compatibility we have to continue even though copying a particular annotation failed.
+ getLogger().error(String.format("Failed to copy parameter annotations from method '%s' of class '%s'",
+ method.getName(), delegateClass.getName()));
+ }
}
}
@@ -460,6 +477,39 @@ public class ClassFabImpl extends Abstra
}
+ private void addMethodParameterAnnotation(final CtMethod ctMethod, final Annotation[][] parameterAnnotations) {
+
+ MethodInfo methodInfo = ctMethod.getMethodInfo();
+
+ ParameterAnnotationsAttribute attribute = (ParameterAnnotationsAttribute) methodInfo
+ .getAttribute(ParameterAnnotationsAttribute.visibleTag);
+
+ if (attribute == null) {
+ attribute = new ParameterAnnotationsAttribute(getConstPool(), ParameterAnnotationsAttribute.visibleTag);
+ }
+
+ List<javassist.bytecode.annotation.Annotation[]> result = CollectionFactory.newList();
+
+ for (Annotation[] next : parameterAnnotations)
+ {
+ List<javassist.bytecode.annotation.Annotation> list = CollectionFactory.newList();
+
+ for (Annotation annotation : next)
+ {
+ final javassist.bytecode.annotation.Annotation copy = toJavassistAnnotation(annotation);
+
+ list.add(copy);
+ }
+
+ result.add(list.toArray(new javassist.bytecode.annotation.Annotation[]{}));
+ }
+
+ javassist.bytecode.annotation.Annotation[][] annotations = result.toArray(new javassist.bytecode.annotation.Annotation[][]{});
+
+ attribute.setAnnotations(annotations);
+
+ methodInfo.addAttribute(attribute);
+ }
private ClassFile getClassFile()
{
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ClassFabImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ClassFabImplTest.java?rev=1035155&r1=1035154&r2=1035155&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ClassFabImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ClassFabImplTest.java Mon Nov 15 06:28:58 2010
@@ -14,9 +14,15 @@
package org.apache.tapestry5.ioc.internal.services;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.util.Arrays.asList;
import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -61,7 +67,7 @@ public class ClassFabImplTest extends IO
public interface AnnotatedService
{
- void doWork(final String value);
+ void doWork(final String value, final String anotherValue);
}
@ServiceId(value = "myService")
@@ -93,11 +99,29 @@ public class ClassFabImplTest extends IO
longValue = 789L,
shortValue = 4,
stringValue = "bar")
- public void doWork(final String value)
+ public void doWork(
+ @TestMethodParameterAnnotation("baz") @TestMethodParameterAnnotation2("foo") final String value,
+ @TestMethodParameterAnnotation("barney") final String anotherValue)
{
}
}
+
+ @Target(PARAMETER )
+ @Retention(RUNTIME)
+ @Documented
+ public @interface TestMethodParameterAnnotation
+ {
+ String value();
+ }
+
+ @Target(PARAMETER )
+ @Retention(RUNTIME)
+ @Documented
+ public @interface TestMethodParameterAnnotation2
+ {
+ String value();
+ }
public ClassFabImplTest()
{
@@ -512,7 +536,7 @@ public class ClassFabImplTest extends IO
assertNotNull(targetClass.getAnnotation(ServiceId.class));
- Method method = targetClass.getMethod("doWork", String.class);
+ Method method = targetClass.getMethod("doWork", String.class, String.class);
TestAnnotation methodAnnotation = method.getAnnotation(TestAnnotation.class);
assertNotNull(methodAnnotation);
@@ -533,6 +557,30 @@ public class ClassFabImplTest extends IO
assertEquals(methodAnnotation.longValue(), 789L);
assertEquals(methodAnnotation.shortValue(), 4);
assertEquals(methodAnnotation.stringValue(), "bar");
+
+ Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+
+ assertEquals(parameterAnnotations.length, 2);
+
+ Annotation[] firstParameterAnnotations = parameterAnnotations[0];
+
+ assertEquals(firstParameterAnnotations.length, 2);
+
+ TestMethodParameterAnnotation first = (TestMethodParameterAnnotation) firstParameterAnnotations[0];
+
+ assertEquals(first.value(), "baz");
+
+ TestMethodParameterAnnotation2 second = (TestMethodParameterAnnotation2) firstParameterAnnotations[1];
+
+ assertEquals(second.value(), "foo");
+
+ Annotation[] secondParameterAnnotation = parameterAnnotations[1];
+
+ assertEquals(secondParameterAnnotation.length, 1);
+
+ first = (TestMethodParameterAnnotation) secondParameterAnnotation[0];
+
+ assertEquals(first.value(), "barney");
}
private void assertContains(String actual, String expectedSubstring)