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)