Adding StubBuilder.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/proxy/branches/version-2.0-work@1508995 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/stub/src/main/java/org/apache/commons/proxy2/stub/StubBuilder.java b/stub/src/main/java/org/apache/commons/proxy2/stub/StubBuilder.java
new file mode 100644
index 0000000..3c2dff7
--- /dev/null
+++ b/stub/src/main/java/org/apache/commons/proxy2/stub/StubBuilder.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.proxy2.stub;
+
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.apache.commons.proxy2.provider.ConstantProvider;
+
+public class StubBuilder<T>
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+    private final ProxyFactory proxyFactory;
+    private final T target;
+    private final StubInterceptorBuilder interceptorBuilder;
+    private final Class<T> type;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+    public StubBuilder(ProxyFactory proxyFactory, Class<T> type)
+    {
+        this.proxyFactory = proxyFactory;
+        this.type = type;
+        this.target = proxyFactory.createInvokerProxy(NullInvoker.INSTANCE, type);
+        this.interceptorBuilder = new StubInterceptorBuilder(proxyFactory);
+    }
+
+    public StubBuilder(ProxyFactory proxyFactory, Class<T> type, ObjectProvider<? extends T> provider)
+    {
+        this.proxyFactory = proxyFactory;
+        this.type = type;
+        this.target = proxyFactory.createDelegatorProxy(provider, type);
+        this.interceptorBuilder = new StubInterceptorBuilder(proxyFactory);
+    }
+
+    public StubBuilder(ProxyFactory proxyFactory, Class<T> type, T target)
+    {
+        this.proxyFactory = proxyFactory;
+        this.type = type;
+        this.target = proxyFactory.createDelegatorProxy(new ConstantProvider<T>(target), type);
+        this.interceptorBuilder = new StubInterceptorBuilder(proxyFactory);
+    }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+    public T build()
+    {
+        return proxyFactory.createInterceptorProxy(target, interceptorBuilder.build(), type);
+    }
+
+    public StubBuilder<T> train(Trainer<T> trainer)
+    {
+        interceptorBuilder.trainFor(type, trainer);
+        return this;
+    }
+}
diff --git a/stub/src/test/java/org/apache/commons/proxy2/stub/StubBuilderTest.java b/stub/src/test/java/org/apache/commons/proxy2/stub/StubBuilderTest.java
new file mode 100644
index 0000000..f391044
--- /dev/null
+++ b/stub/src/test/java/org/apache/commons/proxy2/stub/StubBuilderTest.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.proxy2.stub;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.cglib.CglibProxyFactory;
+import org.apache.commons.proxy2.provider.BeanProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class StubBuilderTest
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+    private ProxyFactory proxyFactory;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+    @Before
+    public void initialize()
+    {
+        proxyFactory = new CglibProxyFactory();
+    }
+
+    @Test
+    public void testWithConcreteTarget()
+    {
+        StubBuilder<StubInterface> builder = new StubBuilder<StubInterface>(proxyFactory, StubInterface.class, new SimpleStub());
+        builder.train(new Trainer<StubInterface>()
+        {
+            @Override
+            protected void train(StubInterface stub)
+            {
+                when(stub.one("Foo")).thenReturn("Bar");
+            }
+        });
+        StubInterface stub = builder.build();
+        assertEquals("Bar", stub.one("Foo"));
+    }
+
+    @Test
+    public void testWithNoTargetAndNoInterceptors()
+    {
+        StubBuilder<StubInterface> builder = new StubBuilder<StubInterface>(proxyFactory, StubInterface.class);
+        StubInterface stub = builder.build();
+        assertNull(stub.one("Whatever"));
+    }
+
+    @Test
+    public void testWithNoTargetWithInterceptor()
+    {
+        StubBuilder<StubInterface> builder = new StubBuilder<StubInterface>(proxyFactory, StubInterface.class);
+        builder.train(new Trainer<StubInterface>()
+        {
+            @Override
+            protected void train(StubInterface stub)
+            {
+                when(stub.one("Foo")).thenReturn("Bar");
+            }
+        });
+        StubInterface stub = builder.build();
+        assertEquals("Bar", stub.one("Foo"));
+    }
+
+    @Test
+    public void testWithObjectProviderTarget()
+    {
+        StubBuilder<StubInterface> builder = new StubBuilder<StubInterface>(proxyFactory, StubInterface.class, new BeanProvider<StubInterface>(SimpleStub.class));
+        builder.train(new Trainer<StubInterface>()
+        {
+            @Override
+            protected void train(StubInterface stub)
+            {
+                when(stub.one("Foo")).thenReturn("Bar");
+            }
+        });
+        StubInterface stub = builder.build();
+        assertEquals("Bar", stub.one("Foo"));
+    }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Inner Classes
+//----------------------------------------------------------------------------------------------------------------------
+
+    private static class SimpleStub implements StubInterface
+    {
+        @Override
+        public String one(String value)
+        {
+            return value;
+        }
+
+        @Override
+        public String three(String arg1, String arg2)
+        {
+            return arg1 + arg2;
+        }
+
+        @Override
+        public String two(String value)
+        {
+            return StringUtils.repeat(value, 2);
+        }
+
+        @Override
+        public byte[] byteArray()
+        {
+            return new byte[]{1, 2, 3};
+        }
+
+        @Override
+        public char[] charArray()
+        {
+            return new char[]{'1', '2', '3'};
+        }
+
+        @Override
+        public short[] shortArray()
+        {
+            return new short[]{1, 2, 3};
+        }
+
+        @Override
+        public int[] intArray()
+        {
+            return new int[]{1, 2, 3};
+        }
+
+        @Override
+        public long[] longArray()
+        {
+            return new long[]{1, 2, 3};
+        }
+
+        @Override
+        public float[] floatArray()
+        {
+            return new float[]{1.0f, 2.0f, 3.0f};
+        }
+
+        @Override
+        public double[] doubleArray()
+        {
+            return new double[]{1.0, 2.0, 3.0};
+        }
+
+        @Override
+        public boolean[] booleanArray()
+        {
+            return new boolean[]{true, false, true};
+        }
+
+        @Override
+        public String[] stringArray()
+        {
+            return new String[] {"One", "Two", "Three"};
+        }
+
+        @Override
+        public String arrayParameter(String... strings)
+        {
+            return StringUtils.join(strings, ", ");
+        }
+
+        @Override
+        public void voidMethod(String arg)
+        {
+
+        }
+    }
+}