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 2012/06/07 17:10:53 UTC

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

Author: mbenson
Date: Thu Jun  7 15:10:52 2012
New Revision: 1347663

URL: http://svn.apache.org/viewvc?rev=1347663&view=rev
Log:
delegating annotation stubs

Modified:
    commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java
    commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfiguration.java
    commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfigurer.java
    commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationFactoryTest.java

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java?rev=1347663&r1=1347662&r2=1347663&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/AnnotationFactory.java Thu Jun  7 15:10:52 2012
@@ -26,6 +26,7 @@ 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.tuple.ImmutablePair;
 import org.apache.commons.proxy2.Interceptor;
 import org.apache.commons.proxy2.Invocation;
@@ -34,6 +35,7 @@ import org.apache.commons.proxy2.ObjectP
 import org.apache.commons.proxy2.ProxyFactory;
 import org.apache.commons.proxy2.ProxyUtils;
 import org.apache.commons.proxy2.impl.AbstractProxyFactory;
+import org.apache.commons.proxy2.provider.ConstantProvider;
 
 /**
  * {@link AnnotationFactory} provides a simplified API over {@link StubProxyFactory}
@@ -164,6 +166,9 @@ public class AnnotationFactory {
 
         @Override
         protected void configure(A stub) {
+            if (attributes == null) {
+                return;
+            }
             When<Object> bud;
             StubConfiguration dy = this;
             for (Map.Entry<String, Object> attr : attributes.entrySet()) {
@@ -251,61 +256,100 @@ public class AnnotationFactory {
      * @return stubbed annotation proxy
      */
     public <A extends Annotation> A create(StubConfigurer<A> configurer) {
-        @SuppressWarnings("unchecked")
-        final A result = (A) createInternal(Thread.currentThread().getContextClassLoader(), configurer);
-        return result;
+        return create(Thread.currentThread().getContextClassLoader(), Validate.notNull(configurer, "null configurer"));
+    }
+
+    /**
+     * Create a delegating annotation of the type supported by <code>configurer</code>.
+     * @param <A>
+     * @param target not {@code null}
+     * @param configurer not {@code null}
+     * @return stubbed annotation proxy
+     */
+    public <A extends Annotation> A createDelegator(A target, StubConfigurer<A> configurer) {
+        return createInternal(Thread.currentThread().getContextClassLoader(),
+            Validate.notNull(target, "null target"), Validate.notNull(configurer, "null configurer"));
     }
 
     /**
      * Create an annotation of the type supported by <code>configurer</code> in the specified classpath.
      * @param <A>
-     * @param classLoader
-     * @param configurer
+     * @param classLoader not {@code null}
+     * @param configurer not {@code null}
      * @return stubbed annotation proxy
      */
     public <A extends Annotation> A create(ClassLoader classLoader, StubConfigurer<A> configurer) {
-        @SuppressWarnings("unchecked")
-        final A result = (A) createInternal(classLoader, configurer);
-        return result;
+        return createInternal(Validate.notNull(classLoader, "null classLoader"),
+            null, Validate.notNull(configurer, "null configurer"));
+    }
+
+    /**
+     * Create a delegating annotation of the type supported by <code>configurer</code> in the specified classpath.
+     * @param <A>
+     * @param classLoader not {@code null}
+     * @param target not {@code null}
+     * @param configurer not {@code null}
+     * @return stubbed annotation proxy
+     */
+    public <A extends Annotation> A createDelegator(ClassLoader classLoader, A target, StubConfigurer<A> configurer) {
+        return createInternal(Validate.notNull(classLoader, "null classLoader"),
+            Validate.notNull(target, "null target"), Validate.notNull(configurer, "null configurer"));
     }
 
     /**
      * Create an annotation of <code>annotationType</code> with fully default behavior.
      * @param <A>
-     * @param classLoader
-     * @param annotationType
+     * @param annotationType not {@code null}
      * @return stubbed annotation proxy
      */
     public <A extends Annotation> A create(Class<A> annotationType) {
         @SuppressWarnings("unchecked")
-        final A result = (A) createInternal(Thread.currentThread().getContextClassLoader(), annotationType);
+        final A result =
+            (A) createInternal(Thread.currentThread().getContextClassLoader(),
+                Validate.notNull(annotationType, "null annotationType"));
         return result;
     }
 
     /**
      * Create an annotation of <code>annotationType</code> with fully default behavior.
      * @param <A>
-     * @param classLoader
-     * @param annotationType
+     * @param classLoader not {@code null}
+     * @param annotationType not {@code null}
      * @return stubbed annotation proxy
      */
     public <A extends Annotation> A create(ClassLoader classLoader, Class<A> annotationType) {
         @SuppressWarnings("unchecked")
-        final A result = (A) createInternal(classLoader, annotationType);
+        final A result =
+            (A) createInternal(Validate.notNull(classLoader, "null classLoader"),
+                Validate.notNull(annotationType, "null annotationType"));
         return result;
     }
 
     /**
      * Create an annotation of <code>annotationType</code> with behavior specified by a {@link String}-keyed {@link Map}.
      * @param <A>
-     * @param classLoader
-     * @param annotationType
+     * @param annotationType not {@code null}
      * @param attributes
      * @return stubbed annotation proxy
      */
     public <A extends Annotation> A create(Class<A> annotationType, Map<String, Object> attributes) {
-        return attributes == null || attributes.isEmpty() ? create(annotationType)
-            : create(new MapBasedAnnotationConfigurer<A>(annotationType, attributes));
+        if (attributes == null || attributes.isEmpty()) {
+            return create(annotationType);
+        }
+        return create(new MapBasedAnnotationConfigurer<A>(annotationType, attributes));
+    }
+
+    /**
+     * Create a delegating annotation of <code>annotationType</code> with behavior specified by a {@link String}-keyed {@link Map}.
+     * @param <A>
+     * @param target not {@code null}
+     * @param attributes
+     * @return stubbed annotation proxy
+     */
+    public <A extends Annotation> A createDelegator(A target, Map<String, Object> attributes) {
+        @SuppressWarnings("unchecked")
+        final Class<A> annotationType = (Class<A>) Validate.notNull(target, "null target").annotationType();
+        return createDelegator(target, new MapBasedAnnotationConfigurer<A>(annotationType, attributes));
     }
 
     /**
@@ -318,11 +362,28 @@ public class AnnotationFactory {
      */
     public <A extends Annotation> A create(ClassLoader classLoader, Class<A> annotationType,
         Map<String, Object> attributes) {
-        return attributes == null || attributes.isEmpty() ? create(classLoader, annotationType) : create(classLoader,
-            new MapBasedAnnotationConfigurer<A>(annotationType, attributes));
+        return create(classLoader, new MapBasedAnnotationConfigurer<A>(annotationType, attributes));
+    }
+
+    /**
+     * Create a delegating annotation of <code>annotationType</code> with behavior specified by a {@link String}-keyed {@link Map}.
+     * @param <A>
+     * @param classLoader
+     * @param target
+     * @param attributes
+     * @return stubbed annotation proxy
+     */
+    public <A extends Annotation> A createDelegator(ClassLoader classLoader, A target, Map<String, Object> attributes) {
+        @SuppressWarnings("unchecked")
+        final Class<A> annotationType = (Class<A>) Validate.notNull(target, "null target").annotationType();
+        return createDelegator(classLoader, target, new MapBasedAnnotationConfigurer<A>(annotationType, attributes));
     }
 
     private <A extends Annotation> A createInternal(ClassLoader classLoader, Object configurer) {
+        return createInternal(classLoader, null, configurer);
+    }
+
+    private <A extends Annotation> A createInternal(ClassLoader classLoader, A target, Object configurer) {
         final Object existingConfigurer = CONFIGURER.get();
         final boolean outerContext = CONTEXT.get() == null;
         try {
@@ -330,8 +391,17 @@ public class AnnotationFactory {
             if (outerContext) {
                 CONTEXT.set(ImmutablePair.of(this, classLoader));
             }
-            @SuppressWarnings("unchecked")
-            final A result = (A) proxyFactory.createInvokerProxy(classLoader, ANNOTATION_INVOKER, getStubType());
+            final A result;
+            if (target == null) {
+                @SuppressWarnings("unchecked")
+                A invoker = (A) proxyFactory.createInvokerProxy(classLoader, ANNOTATION_INVOKER, getStubType());
+                result = invoker;
+            } else {
+                @SuppressWarnings("unchecked")
+                A delegator =
+                    (A) proxyFactory.createDelegatorProxy(classLoader, new ConstantProvider<A>(target), getStubType());
+                result = delegator;
+            }
             return validate(result);
         } finally {
             if (existingConfigurer == null) {

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfiguration.java?rev=1347663&r1=1347662&r2=1347663&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfiguration.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfiguration.java Thu Jun  7 15:10:52 2012
@@ -17,12 +17,16 @@
 
 package org.apache.commons.proxy2.stub;
 
+import org.apache.commons.functor.UnaryPredicate;
 import org.apache.commons.proxy2.ObjectProvider;
 
 /**
  * Fluent stub configuration interface inspired by Mockito stubbing mechanisms.
- * This interface declares all the methods necessary to, in particular, allow
- * varargs to be used to specify return values for any array type.
+ * This interface declares all the methods necessary to:
+ * <ul>
+ * <li>allow varargs to be used to specify return values for any array type</li>
+ * <li>make interactive stub calls describe nonspecific argument matching situations</li>
+ * </ul>
  */
 public interface StubConfiguration {
 
@@ -344,4 +348,67 @@ public interface StubConfiguration {
      */
     WhenClass when(Class<?> call);
 
+    /**
+     * Match any boolean.
+     * @return mock argument
+     */
+    boolean anyBoolean();
+
+    /**
+     * Match any byte.
+     * @return mock argument
+     */
+    byte anyByte();
+
+    /**
+     * Match any short.
+     * @return mock argument
+     */
+    short anyShort();
+
+    /**
+     * Match any int.
+     * @return mock argument
+     */
+    int anyInt();
+
+    /**
+     * Match any char.
+     * @return mock argument
+     */
+    char anyChar();
+
+    /**
+     * Match any long.
+     * @return mock argument
+     */
+    long anyLong();
+
+    /**
+     * Match any float.
+     * @return mock argument
+     */
+    float anyFloat();
+
+    /**
+     * Match any double.
+     * @return mock argument
+     */
+    double anyDouble();
+
+    /**
+     * Match any object.
+     * @param <T>
+     * @return mock argument
+     */
+    <T> T any();
+
+    /**
+     * Match an argument with a test.
+     * @param <T>
+     * @param test
+     * @return mock argument
+     */
+    <T> T argThat(UnaryPredicate<T> test);
+
 }

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfigurer.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfigurer.java?rev=1347663&r1=1347662&r2=1347663&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfigurer.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/main/java/org/apache/commons/proxy2/stub/StubConfigurer.java Thu Jun  7 15:10:52 2012
@@ -17,11 +17,13 @@
 
 package org.apache.commons.proxy2.stub;
 
+import org.apache.commons.functor.UnaryPredicate;
 import org.apache.commons.lang3.reflect.TypeUtils;
 import org.apache.commons.proxy2.ObjectProvider;
 import org.apache.commons.proxy2.provider.ConstantProvider;
 
 /**
+ * <p>
  * Configuration mechanism for a stub.  Implements {@link StubConfiguration} for maximum fluency.
  * A {@link StubConfigurer} needs to know the type of stub object to which it applies.
  * Any useful runtime subclass should have the type variable non-generically
@@ -34,7 +36,11 @@ import org.apache.commons.proxy2.provide
  *     }
  * }
  * </pre></code>
+ * </p>
  *
+ * <p>Note that when argument matching is used, all method parameters must be specified using matchers.
+ * TODO add matching example
+ * </p>
  * @param <T>
  * @author Matt Benson
  */
@@ -65,12 +71,11 @@ public abstract class StubConfigurer<T> 
             return;
         }
         @SuppressWarnings("unchecked")
-        final Class<T> resolvedVariable = (Class<T>) TypeUtils.getRawType(
-                StubConfigurer.class.getTypeParameters()[0], getClass());
+        final Class<T> resolvedVariable =
+            (Class<T>) TypeUtils.getRawType(StubConfigurer.class.getTypeParameters()[0], getClass());
         if (resolvedVariable == null) {
-            throw new IllegalArgumentException(
-                    "stubType was not specified and could not be calculated for "
-                            + getClass());
+            throw new IllegalArgumentException("stubType was not specified and could not be calculated for "
+                + getClass());
         }
         this.stubType = resolvedVariable;
     }
@@ -86,8 +91,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public <RT> org.apache.commons.proxy2.stub.StubConfiguration.When<RT> when(
-            RT call) {
+    public <RT> org.apache.commons.proxy2.stub.StubConfiguration.When<RT> when(RT call) {
         return new When<RT>() {
 
             public StubConfiguration thenReturn(RT result) {
@@ -95,8 +99,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<? extends RT> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<? extends RT> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -105,8 +108,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -116,8 +118,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenBooleanArray when(
-            boolean[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenBooleanArray when(boolean[] call) {
         return new WhenBooleanArray() {
 
             public StubConfiguration thenReturn(boolean... b) {
@@ -125,8 +126,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<boolean[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<boolean[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -135,8 +135,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -146,8 +145,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenByteArray when(
-            byte[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenByteArray when(byte[] call) {
         return new WhenByteArray() {
 
             public StubConfiguration thenReturn(byte... b) {
@@ -155,8 +153,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<byte[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<byte[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -165,8 +162,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -176,8 +172,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenShortArray when(
-            short[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenShortArray when(short[] call) {
         return new WhenShortArray() {
 
             public StubConfiguration thenReturn(short... s) {
@@ -185,8 +180,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<short[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<short[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -195,8 +189,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -206,8 +199,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenIntArray when(
-            int[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenIntArray when(int[] call) {
         return new WhenIntArray() {
 
             public StubConfiguration thenReturn(int... i) {
@@ -215,8 +207,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<int[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<int[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -225,8 +216,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -236,8 +226,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenCharArray when(
-            char[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenCharArray when(char[] call) {
         return new WhenCharArray() {
 
             public StubConfiguration thenReturn(char... c) {
@@ -245,8 +234,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<char[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<char[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -255,8 +243,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -266,8 +253,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenLongArray when(
-            long[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenLongArray when(long[] call) {
         return new WhenLongArray() {
 
             public StubConfiguration thenReturn(long... l) {
@@ -275,8 +261,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<long[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<long[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -285,8 +270,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -296,8 +280,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenFloatArray when(
-            float[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenFloatArray when(float[] call) {
         return new WhenFloatArray() {
 
             public StubConfiguration thenReturn(float... f) {
@@ -305,8 +288,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<float[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<float[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -315,8 +297,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -326,8 +307,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenDoubleArray when(
-            double[] call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenDoubleArray when(double[] call) {
         return new WhenDoubleArray() {
 
             public StubConfiguration thenReturn(double... d) {
@@ -335,8 +315,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<double[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<double[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -345,8 +324,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -356,8 +334,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public <C> org.apache.commons.proxy2.stub.StubConfiguration.WhenObjectArray<C> when(
-            C[] call) {
+    public <C> org.apache.commons.proxy2.stub.StubConfiguration.WhenObjectArray<C> when(C[] call) {
         return new WhenObjectArray<C>() {
 
             public StubConfiguration thenReturn(C... c) {
@@ -365,8 +342,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<C[]> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<C[]> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -375,8 +351,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -386,8 +361,7 @@ public abstract class StubConfigurer<T> 
     /**
      * {@inheritDoc}
      */
-    public org.apache.commons.proxy2.stub.StubConfiguration.WhenClass when(
-            Class<?> call) {
+    public org.apache.commons.proxy2.stub.StubConfiguration.WhenClass when(Class<?> call) {
         return new WhenClass() {
 
             public StubConfiguration thenReturn(Class<?> c) {
@@ -395,8 +369,7 @@ public abstract class StubConfigurer<T> 
                 return StubConfigurer.this;
             }
 
-            public StubConfiguration thenAnswer(
-                    ObjectProvider<Class<?>> objectProvider) {
+            public StubConfiguration thenAnswer(ObjectProvider<Class<?>> objectProvider) {
                 requireStubInterceptor().addAnswer(objectProvider);
                 return StubConfigurer.this;
             }
@@ -405,8 +378,7 @@ public abstract class StubConfigurer<T> 
                 return thenThrow(new ConstantProvider<Throwable>(t));
             }
 
-            public StubConfiguration thenThrow(
-                    ObjectProvider<? extends Throwable> throwableProvider) {
+            public StubConfiguration thenThrow(ObjectProvider<? extends Throwable> throwableProvider) {
                 requireStubInterceptor().addThrow(throwableProvider);
                 return StubConfigurer.this;
             }
@@ -414,13 +386,102 @@ public abstract class StubConfigurer<T> 
     }
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean anyBoolean() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public byte anyByte() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public short anyShort() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int anyInt() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public char anyChar() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long anyLong() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public float anyFloat() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double anyDouble() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <U> U any() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <U> U argThat(UnaryPredicate<U> test) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /**
      * Apply thyself against the specified stub interceptor.
      * @param stubInterceptor
      */
     final void configure(StubInterceptor stubInterceptor, T stub) {
         if (stubInterceptor == null) {
-            throw new IllegalArgumentException(
-                    "Cannot configure null StubInterceptor");
+            throw new IllegalArgumentException("Cannot configure null StubInterceptor");
         }
         synchronized (this) {
             this.stubInterceptor = stubInterceptor;

Modified: commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationFactoryTest.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationFactoryTest.java?rev=1347663&r1=1347662&r2=1347663&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationFactoryTest.java (original)
+++ commons/proper/proxy/branches/version-2.0-work/stub/src/test/java/org/apache/commons/proxy2/stub/AnnotationFactoryTest.java Thu Jun  7 15:10:52 2012
@@ -22,9 +22,13 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertNotNull;
 
 import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.lang3.reflect.FieldUtils;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -32,6 +36,7 @@ import org.junit.Test;
  * Test {@link AnnotationFactory}.
  */
 public class AnnotationFactoryTest {
+    @CustomAnnotation(annString = "FOO", finiteValues = { FiniteValues.ONE, FiniteValues.TWO, FiniteValues.THREE }, someType = Object.class)
     private AnnotationFactory annotationFactory;
 
     @Before
@@ -167,12 +172,65 @@ public class AnnotationFactoryTest {
         annotationFactory.create(CustomAnnotation.class, attributes);
     }
 
+    @Test
+    public void testDelegator() {
+        final boolean forceAccess = true;
+        final CustomAnnotation sourceAnnotation =
+            FieldUtils.getDeclaredField(AnnotationFactoryTest.class, "annotationFactory", forceAccess).getAnnotation(
+                CustomAnnotation.class);
+        assertNotNull(sourceAnnotation);
+        CustomAnnotation stub =
+            annotationFactory.createDelegator(sourceAnnotation, new AnnotationConfigurer<CustomAnnotation>() {
+
+                @Override
+                protected void configure(CustomAnnotation stub) {
+                    when(stub.finiteValues()).thenReturn(FiniteValues.ONE);
+                }
+            });
+        assertEquals(CustomAnnotation.class, stub.annotationType());
+        assertEquals(Object.class, stub.someType());
+        assertEquals("FOO", stub.annString());
+        assertArrayEquals(new FiniteValues[] { FiniteValues.ONE }, stub.finiteValues());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testDelegatorMissingTarget() {
+        annotationFactory.createDelegator(null, new StubConfigurer<CustomAnnotation>() {
+
+            @Override
+            protected void configure(CustomAnnotation stub) {
+            }
+        });
+    }
+
+    @Test
+    public void testDelegatorWithAttributes() {
+        final boolean forceAccess = true;
+        final CustomAnnotation sourceAnnotation =
+            FieldUtils.getDeclaredField(AnnotationFactoryTest.class, "annotationFactory", forceAccess).getAnnotation(
+                CustomAnnotation.class);
+        assertNotNull(sourceAnnotation);
+        Map<String, Object> attributes =
+            Collections.<String, Object> singletonMap("finiteValues", new FiniteValues[] { FiniteValues.ONE });
+        CustomAnnotation stub = annotationFactory.createDelegator(sourceAnnotation, attributes);
+        assertEquals(CustomAnnotation.class, stub.annotationType());
+        assertEquals(Object.class, stub.someType());
+        assertEquals("FOO", stub.annString());
+        assertArrayEquals(new FiniteValues[] { FiniteValues.ONE }, stub.finiteValues());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testDelegatorWithAttributesMissingTarget() {
+        annotationFactory.createDelegator(null, Collections.<String, Object> emptyMap());
+    }
+
     public @interface NestingAnnotation {
         CustomAnnotation child();
 
         String somethingElse();
     }
 
+    @Retention(RetentionPolicy.RUNTIME)
     public @interface CustomAnnotation {
         String annString() default "";