You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2013/08/28 00:33:59 UTC

svn commit: r1518025 - in /commons/proper/proxy/branches/version-2.0-work/stub/src: main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java

Author: mbenson
Date: Tue Aug 27 22:33:58 2013
New Revision: 1518025

URL: http://svn.apache.org/r1518025
Log:
support map-based annotation stubbing

Modified:
    commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
    commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java?rev=1518025&r1=1518024&r2=1518025&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java Tue Aug 27 22:33:58 2013
@@ -22,8 +22,11 @@ import java.lang.reflect.InvocationHandl
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.util.Map;
 
 import org.apache.commons.lang3.AnnotationUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.reflect.TypeUtils;
 import org.apache.commons.proxy2.Interceptor;
 import org.apache.commons.proxy2.Invocation;
 import org.apache.commons.proxy2.Invoker;
@@ -159,6 +162,44 @@ public class AnnotationBuilder<A extends
         }
     };
 
+    private class MapAnnotationTrainer extends AnnotationTrainer<A>
+    {
+        final Map<String, ?> members;
+
+        MapAnnotationTrainer(Map<String, ?> members)
+        {
+            super(type);
+            this.members = members;
+        }
+
+        @Override
+        protected void train(A trainee)
+        {
+            WhenObject<Object> bud;
+            AnnotationTrainer<A> dy = this;
+            for (Map.Entry<String, ?> attr : members.entrySet()) {
+                final Method m;
+                try {
+                    m = traineeType.getDeclaredMethod(attr.getKey());
+                } catch (Exception e1) {
+                    throw new IllegalArgumentException(String.format("Could not detect annotation member %1$s",
+                        attr.getKey()));
+                }
+                try {
+                    bud = dy.when(m.invoke(trainee));
+                } catch (Exception e) {
+                    //it must have happened on the invoke, so we didn't call when... it shouldn't happen, but we'll simply skip:
+                    continue;
+                }
+                final Object value = attr.getValue();
+                Validate.isTrue(TypeUtils.isInstance(value, m.getReturnType()),
+                        "Value %s can not be assigned to %s", value,
+                        m.getReturnType());
+                dy = bud.thenReturn(value);
+            }
+        }
+    }
+
     public static <A extends Annotation> A buildDefault(Class<A> type)
     {
         return of(type).build();
@@ -194,6 +235,11 @@ public class AnnotationBuilder<A extends
         super(PROXY_FACTORY, type, target);
     }
 
+    public AnnotationBuilder<A> withMembers(Map<String, ?> members)
+    {
+        return train(new MapAnnotationTrainer(members));
+    }
+
     @Override
     public AnnotationBuilder<A> train(BaseTrainer<?, A> trainer)
     {

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java?rev=1518025&r1=1518024&r2=1518025&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java Tue Aug 27 22:33:58 2013
@@ -19,8 +19,13 @@ package org.apache.commons.proxy2.stub;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.junit.Test;
 
 /**
@@ -78,6 +83,29 @@ public class AnnotationBuilderTest
         assertEquals("somethingElse", nestingAnnotation.somethingElse());
     }
 
+    @Test
+    public void testMemberMap()
+    {
+        final Map<String, Object> members = new HashMap<String, Object>();
+        members.put("annString", "foo");
+        members.put("finiteValues", FiniteValues.values());
+        members.put("someType", Object.class);
+
+        final CustomAnnotation customAnnotation = AnnotationBuilder.of(CustomAnnotation.class).withMembers(members).build();
+        		
+        assertNotNull(customAnnotation);
+        assertEquals(CustomAnnotation.class, customAnnotation.annotationType());
+        assertEquals("foo", customAnnotation.annString());
+        assertEquals(3, customAnnotation.finiteValues().length);
+        assertEquals(Object.class, customAnnotation.someType());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBadMemberMap()
+    {
+        AnnotationBuilder.of(CustomAnnotation.class).withMembers(Collections.singletonMap("annString", Integer.valueOf(100)));
+    }
+
     public @interface NestingAnnotation
     {
         CustomAnnotation child();