make 2.0 branch into trunk
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/proxy/trunk@1579340 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/NOTICE.txt b/NOTICE.txt
index b8e091f..0075441 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
Apache Commons Proxy
Copyright 2005-2008 The Apache Software Foundation
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/PROPOSAL.html b/PROPOSAL.html
index 82499cd..ddaa1fd 100644
--- a/PROPOSAL.html
+++ b/PROPOSAL.html
@@ -6,7 +6,7 @@
~ (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
+ ~ 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,
@@ -14,6 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
+
<html>
<head>
<title>Proposal for Proxy Package</title>
diff --git a/asm4/pom.xml b/asm4/pom.xml
new file mode 100644
index 0000000..90318f5
--- /dev/null
+++ b/asm4/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy2-asm4</artifactId>
+ <name>Commons Proxy ASM4 Proxies Module</name>
+ <description>Proxies based on classes dynamically generated using ASM v4
+ </description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm-commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/asm4/src/main/java/org/apache/commons/proxy2/asm4/ASM4ProxyFactory.java b/asm4/src/main/java/org/apache/commons/proxy2/asm4/ASM4ProxyFactory.java
new file mode 100644
index 0000000..57ed58f
--- /dev/null
+++ b/asm4/src/main/java/org/apache/commons/proxy2/asm4/ASM4ProxyFactory.java
@@ -0,0 +1,470 @@
+/*
+ * 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.asm4;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+import org.apache.commons.proxy2.impl.AbstractProxyClassGenerator;
+import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;
+import org.apache.commons.proxy2.impl.ProxyClassCache;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.GeneratorAdapter;
+
+public class ASM4ProxyFactory extends AbstractSubclassingProxyFactory
+{
+ private static final ProxyClassCache PROXY_CLASS_CACHE = new ProxyClassCache(new ProxyGenerator());
+
+ @Override
+ public <T> T createDelegatorProxy(final ClassLoader classLoader, final ObjectProvider<?> delegateProvider,
+ final Class<?>... proxyClasses)
+ {
+ return createProxy(classLoader, new DelegatorInvoker(delegateProvider), proxyClasses);
+ }
+
+ @Override
+ public <T> T createInterceptorProxy(final ClassLoader classLoader, final Object target,
+ final Interceptor interceptor, final Class<?>... proxyClasses)
+ {
+ return createProxy(classLoader, new InterceptorInvoker(target, interceptor), proxyClasses);
+ }
+
+ @Override
+ public <T> T createInvokerProxy(final ClassLoader classLoader, final Invoker invoker,
+ final Class<?>... proxyClasses)
+ {
+ return createProxy(classLoader, new InvokerInvoker(invoker), proxyClasses);
+ }
+
+ private <T> T createProxy(final ClassLoader classLoader, final AbstractInvoker invoker,
+ final Class<?>... proxyClasses)
+ {
+ final Class<?> proxyClass = PROXY_CLASS_CACHE.getProxyClass(classLoader, proxyClasses);
+ try
+ {
+ @SuppressWarnings("unchecked")
+ final T result = (T) proxyClass.getConstructor(Invoker.class).newInstance(invoker);
+ return result;
+ }
+ catch (Exception e)
+ {
+ throw e instanceof RuntimeException ? ((RuntimeException) e) : new RuntimeException(e);
+ }
+ }
+
+ private static class ProxyGenerator extends AbstractProxyClassGenerator implements Opcodes
+ {
+ private static final AtomicInteger CLASS_NUMBER = new AtomicInteger(0);
+ private static final String CLASSNAME_PREFIX = "CommonsProxyASM4_";
+ private static final String HANDLER_NAME = "__handler";
+ private static final Type INVOKER_TYPE = Type.getType(Invoker.class);
+
+ @Override
+ public Class<?> generateProxyClass(final ClassLoader classLoader, final Class<?>... proxyClasses)
+ {
+ final Class<?> superclass = getSuperclass(proxyClasses);
+ final String proxyName = CLASSNAME_PREFIX + CLASS_NUMBER.incrementAndGet();
+ final Method[] implementationMethods = getImplementationMethods(proxyClasses);
+ final Class<?>[] interfaces = toInterfaces(proxyClasses);
+ final String classFileName = proxyName.replace('.', '/');
+
+ try
+ {
+ final byte[] proxyBytes = generateProxy(superclass, classFileName, implementationMethods, interfaces);
+ return loadClass(classLoader, proxyName, proxyBytes);
+ }
+ catch (final Exception e)
+ {
+ throw new ProxyFactoryException(e);
+ }
+ }
+
+ private static byte[] generateProxy(final Class<?> classToProxy, final String proxyName,
+ final Method[] methods, final Class<?>... interfaces) throws ProxyFactoryException
+ {
+ final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+ final Type proxyType = Type.getObjectType(proxyName);
+
+ // push class signature
+ final String[] interfaceNames = new String[interfaces.length];
+ for (int i = 0; i < interfaces.length; i++)
+ {
+ interfaceNames[i] = Type.getType(interfaces[i]).getInternalName();
+ }
+
+ final Type superType = Type.getType(classToProxy);
+ cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, proxyType.getInternalName(), null, superType.getInternalName(),
+ interfaceNames);
+
+ // create Invoker field
+ cw.visitField(ACC_FINAL + ACC_PRIVATE, HANDLER_NAME, INVOKER_TYPE.getDescriptor(), null, null).visitEnd();
+
+ init(cw, proxyType, superType);
+
+ for (final Method method : methods)
+ {
+ processMethod(cw, method, proxyType, HANDLER_NAME);
+ }
+
+ return cw.toByteArray();
+ }
+
+ private static void init(final ClassWriter cw, final Type proxyType, Type superType)
+ {
+ final GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, new org.objectweb.asm.commons.Method("<init>",
+ Type.VOID_TYPE, new Type[] { INVOKER_TYPE }), null, null, cw);
+ // invoke super constructor:
+ mg.loadThis();
+ mg.invokeConstructor(superType, org.objectweb.asm.commons.Method.getMethod("void <init> ()"));
+
+ // assign handler:
+ mg.loadThis();
+ mg.loadArg(0);
+ mg.putField(proxyType, HANDLER_NAME, INVOKER_TYPE);
+ mg.returnValue();
+ mg.endMethod();
+ }
+
+ private static void processMethod(final ClassWriter cw, final Method method, final Type proxyType,
+ final String handlerName) throws ProxyFactoryException
+ {
+ final Type sig = Type.getType(method);
+ final Type[] exceptionTypes = getTypes(method.getExceptionTypes());
+
+ // push the method definition
+ final int access = (ACC_PUBLIC | ACC_PROTECTED) & method.getModifiers();
+ final org.objectweb.asm.commons.Method m = org.objectweb.asm.commons.Method.getMethod(method);
+ final GeneratorAdapter mg = new GeneratorAdapter(access, m, null, getTypes(method.getExceptionTypes()), cw);
+
+ final Label tryBlock = exceptionTypes.length > 0 ? mg.mark() : null;
+
+ mg.push(Type.getType(method.getDeclaringClass()));
+
+ // the following code generates the bytecode for this line of Java:
+ // Method method = <proxy>.class.getMethod("add", new Class[] {
+ // <array of function argument classes> });
+
+ // get the method name to invoke, and push to stack
+
+ mg.push(method.getName());
+
+ // create the Class[]
+ mg.push(sig.getArgumentTypes().length);
+ final Type classType = Type.getType(Class.class);
+ mg.newArray(classType);
+
+ // push parameters into array
+ for (int i = 0; i < sig.getArgumentTypes().length; i++)
+ {
+ // keep copy of array on stack
+ mg.dup();
+
+ // push index onto stack
+ mg.push(i);
+ mg.push(sig.getArgumentTypes()[i]);
+ mg.arrayStore(classType);
+ }
+
+ // invoke getMethod() with the method name and the array of types
+ mg.invokeVirtual(classType, org.objectweb.asm.commons.Method
+ .getMethod("java.lang.reflect.Method getDeclaredMethod(String, Class[])"));
+ // store the returned method for later
+
+ // the following code generates bytecode equivalent to:
+ // return ((<returntype>) invoker.invoke(this, method, new Object[]
+ // { <function arguments }))[.<primitive>Value()];
+
+ mg.loadThis();
+
+ mg.getField(proxyType, handlerName, INVOKER_TYPE);
+ // put below method:
+ mg.swap();
+
+ // we want to pass "this" in as the first parameter
+ mg.loadThis();
+ // put below method:
+ mg.swap();
+
+ // need to construct the array of objects passed in
+
+ // create the Object[]
+ mg.push(sig.getArgumentTypes().length);
+ final Type objectType = Type.getType(Object.class);
+ mg.newArray(objectType);
+
+ // push parameters into array
+ for (int i = 0; i < sig.getArgumentTypes().length; i++)
+ {
+ // keep copy of array on stack
+ mg.dup();
+
+ // push index onto stack
+ mg.push(i);
+
+ mg.loadArg(i);
+ mg.valueOf(sig.getArgumentTypes()[i]);
+ mg.arrayStore(objectType);
+ }
+
+ // invoke the invoker
+ mg.invokeInterface(INVOKER_TYPE, org.objectweb.asm.commons.Method
+ .getMethod("Object invoke(Object, java.lang.reflect.Method, Object[])"));
+
+ // cast the result
+ mg.unbox(sig.getReturnType());
+
+ // push return
+ mg.returnValue();
+
+ // catch InvocationTargetException
+ if (exceptionTypes.length > 0)
+ {
+ final Type caughtExceptionType = Type.getType(InvocationTargetException.class);
+ mg.catchException(tryBlock, mg.mark(), caughtExceptionType);
+
+ final Label throwCause = new Label();
+
+ mg.invokeVirtual(caughtExceptionType,
+ org.objectweb.asm.commons.Method.getMethod("Throwable getCause()"));
+
+ for (int i = 0; i < exceptionTypes.length; i++)
+ {
+ mg.dup();
+ mg.push(exceptionTypes[i]);
+ mg.swap();
+ mg.invokeVirtual(classType,
+ org.objectweb.asm.commons.Method.getMethod("boolean isInstance(Object)"));
+ // if true, throw cause:
+ mg.ifZCmp(GeneratorAdapter.NE, throwCause);
+ }
+ // no exception types matched; throw
+ // UndeclaredThrowableException:
+ final int cause = mg.newLocal(Type.getType(Exception.class));
+ mg.storeLocal(cause);
+ final Type undeclaredType = Type.getType(UndeclaredThrowableException.class);
+ mg.newInstance(undeclaredType);
+ mg.dup();
+ mg.loadLocal(cause);
+ mg.invokeConstructor(undeclaredType, new org.objectweb.asm.commons.Method("<init>", Type.VOID_TYPE,
+ new Type[] { Type.getType(Throwable.class) }));
+ mg.throwException();
+
+ mg.mark(throwCause);
+ mg.throwException();
+ }
+
+ // finish this method
+ mg.endMethod();
+ }
+
+ private static Type[] getTypes(Class<?>... src)
+ {
+ final Type[] result = new Type[src.length];
+ for (int i = 0; i < result.length; i++)
+ {
+ result[i] = Type.getType(src[i]);
+ }
+ return result;
+ }
+
+ /**
+ * Adapted from http://asm.ow2.org/doc/faq.html#Q5
+ *
+ * @param b
+ * @return Class<?>
+ */
+ private static Class<?> loadClass(final ClassLoader loader, String className, byte[] b)
+ {
+ // override classDefine (as it is protected) and define the class.
+ try
+ {
+ final Method method = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class,
+ int.class, int.class);
+
+ // protected method invocation
+ final boolean accessible = method.isAccessible();
+ if (!accessible)
+ {
+ method.setAccessible(true);
+ }
+ try
+ {
+ return (Class<?>) method
+ .invoke(loader, className, b, Integer.valueOf(0), Integer.valueOf(b.length));
+ }
+ finally
+ {
+ if (!accessible)
+ {
+ method.setAccessible(false);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw e instanceof RuntimeException ? ((RuntimeException) e) : new RuntimeException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("serial")
+ private static class DelegatorInvoker extends AbstractInvoker
+ {
+ private final ObjectProvider<?> delegateProvider;
+
+ protected DelegatorInvoker(ObjectProvider<?> delegateProvider)
+ {
+ this.delegateProvider = delegateProvider;
+ }
+
+ public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ try
+ {
+ return method.invoke(delegateProvider.getObject(), args);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw e.getTargetException();
+ }
+ }
+ }
+
+ @SuppressWarnings("serial")
+ private static class InterceptorInvoker extends AbstractInvoker
+ {
+ private final Object target;
+ private final Interceptor methodInterceptor;
+
+ public InterceptorInvoker(Object target, Interceptor methodInterceptor)
+ {
+ this.target = target;
+ this.methodInterceptor = methodInterceptor;
+ }
+
+ public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ final ReflectionInvocation invocation = new ReflectionInvocation(target, proxy, method, args);
+ return methodInterceptor.intercept(invocation);
+ }
+ }
+
+ @SuppressWarnings("serial")
+ private abstract static class AbstractInvoker implements Invoker, Serializable
+ {
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ if (isHashCode(method))
+ {
+ return System.identityHashCode(proxy);
+ }
+ if (isEqualsMethod(method))
+ {
+ return proxy == args[0];
+ }
+ return invokeImpl(proxy, method, args);
+ }
+
+ protected abstract Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable;
+ }
+
+ @SuppressWarnings("serial")
+ private static class InvokerInvoker extends AbstractInvoker
+ {
+ private final Invoker invoker;
+
+ public InvokerInvoker(Invoker invoker)
+ {
+ this.invoker = invoker;
+ }
+
+ public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ return invoker.invoke(proxy, method, args);
+ }
+ }
+
+ protected static boolean isHashCode(Method method)
+ {
+ return "hashCode".equals(method.getName()) && Integer.TYPE.equals(method.getReturnType())
+ && method.getParameterTypes().length == 0;
+ }
+
+ protected static boolean isEqualsMethod(Method method)
+ {
+ return "equals".equals(method.getName()) && Boolean.TYPE.equals(method.getReturnType())
+ && method.getParameterTypes().length == 1 && Object.class.equals(method.getParameterTypes()[0]);
+ }
+
+ @SuppressWarnings("serial")
+ private static class ReflectionInvocation implements Invocation, Serializable
+ {
+ private final Method method;
+ private final Object[] arguments;
+ private final Object proxy;
+ private final Object target;
+
+ public ReflectionInvocation(final Object target, final Object proxy, final Method method,
+ final Object[] arguments)
+ {
+ this.method = method;
+ this.arguments = (arguments == null ? ProxyUtils.EMPTY_ARGUMENTS : arguments);
+ this.proxy = proxy;
+ this.target = target;
+ }
+
+ public Object[] getArguments()
+ {
+ return arguments;
+ }
+
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public Object getProxy()
+ {
+ return proxy;
+ }
+
+ public Object proceed() throws Throwable
+ {
+ try
+ {
+ return method.invoke(target, arguments);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw e.getTargetException();
+ }
+ }
+ }
+}
diff --git a/src/test/resources/log4j.properties b/asm4/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
similarity index 75%
copy from src/test/resources/log4j.properties
copy to asm4/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
index b981287..529137c 100644
--- a/src/test/resources/log4j.properties
+++ b/asm4/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
@@ -14,7 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-log4j.rootLogger=DEBUG, console
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p (%c{1}) %3x - %m%n
\ No newline at end of file
+org.apache.commons.proxy2.asm4.ASM4ProxyFactory
diff --git a/asm4/src/site/markdown/index.md b/asm4/src/site/markdown/index.md
new file mode 100644
index 0000000..10fc4cd
--- /dev/null
+++ b/asm4/src/site/markdown/index.md
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+## Commons Proxy ASM4
+
+Provides the [ASM4ProxyFactory][] which uses the [ASM][] library (v4.x)
+to create proxy classes. This proxy factory is capable of proxying concrete
+non-`final` types and can thus be considered a *subclassing* proxy factory.
+
+[ASM4ProxyFactory]: apidocs/org/apache/commons/proxy2/asm4/ASM4ProxyFactory.html
+
+[ASM]: http://asm.ow2.org/
diff --git a/asm4/src/test/java/org/apache/commons/proxy2/asm4/TestAsm4ProxyFactory.java b/asm4/src/test/java/org/apache/commons/proxy2/asm4/TestAsm4ProxyFactory.java
new file mode 100644
index 0000000..7808e84
--- /dev/null
+++ b/asm4/src/test/java/org/apache/commons/proxy2/asm4/TestAsm4ProxyFactory.java
@@ -0,0 +1,10 @@
+package org.apache.commons.proxy2.asm4;
+
+import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;
+
+public class TestAsm4ProxyFactory extends AbstractSubclassingProxyFactoryTestCase
+{
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+}
diff --git a/build-tools/pom.xml b/build-tools/pom.xml
new file mode 100644
index 0000000..e2996ab
--- /dev/null
+++ b/build-tools/pom.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>commons-proxy2-build-tools</artifactId>
+ <name>Commons Proxy Build Tools</name>
+ <description>Provide common setup, from http://maven.apache.org/plugins/maven-checkstyle-plugin/examples/multi-module-config.html</description>
+</project>
diff --git a/build-tools/src/main/resources/org/apache/commons/proxy2/checkstyle.xml b/build-tools/src/main/resources/org/apache/commons/proxy2/checkstyle.xml
new file mode 100644
index 0000000..0ed8c5b
--- /dev/null
+++ b/build-tools/src/main/resources/org/apache/commons/proxy2/checkstyle.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+
+<!--
+ ~ 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.
+ -->
+<!DOCTYPE module PUBLIC
+ "-//Puppy Crawl//DTD Check Configuration 1.1//EN"
+ "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
+
+<!-- commons proxy2 customization of default Checkstyle behavior -->
+<module name="Checker">
+ <property name="localeLanguage" value="en"/>
+
+ <module name="Header">
+ <property name="headerFile" value="${checkstyle.header.file}"/>
+ </module>
+
+ <!-- no tabs allowed in files -->
+ <module name="FileTabCharacter"/>
+
+ <module name="TreeWalker">
+ <!-- Verify that EVERY source file has the appropriate license -->
+ <!-- check sane import statements -->
+ <module name="AvoidStarImport"/>
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+
+ <module name="LineLength">
+ <property name="max" value="120"/>
+ </module>
+ </module>
+</module>
diff --git a/license-header.txt b/build-tools/src/main/resources/org/apache/commons/proxy2/license-header.txt
similarity index 100%
rename from license-header.txt
rename to build-tools/src/main/resources/org/apache/commons/proxy2/license-header.txt
diff --git a/cglib/pom.xml b/cglib/pom.xml
new file mode 100644
index 0000000..ce16287
--- /dev/null
+++ b/cglib/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy2-cglib</artifactId>
+ <name>Commons Proxy CGLIB Proxies Module</name>
+ <description>Proxies based on classes dynamically generated using cglib
+ </description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib-nodep</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java b/cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java
similarity index 67%
rename from src/main/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java
rename to cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java
index 09aa42d..623e64b 100644
--- a/src/main/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java
+++ b/cglib/src/main/java/org/apache/commons/proxy2/cglib/CglibProxyFactory.java
@@ -1,218 +1,232 @@
-/*
- * 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.proxy.factory.cglib;
-
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Dispatcher;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.MethodProxy;
-import net.sf.cglib.proxy.MethodInterceptor;
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.factory.util.AbstractSubclassingProxyFactory;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-/**
- * A <a href="http://cglib.sourceforge.net/">CGLIB</a>-based {@link org.apache.commons.proxy.ProxyFactory}
- * implementation.
- * <p/>
- * <p/>
- * <b>Dependencies</b>: <ul> <li>CGLIB version 2.0.2 or greater</li> </ul> </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class CglibProxyFactory extends AbstractSubclassingProxyFactory
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static CallbackFilter callbackFilter = new CglibProxyFactoryCallbackFilter();
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public Object createDelegatorProxy(ClassLoader classLoader, ObjectProvider targetProvider,
- Class[] proxyClasses)
- {
- final Enhancer enhancer = new Enhancer();
- enhancer.setClassLoader(classLoader);
- enhancer.setInterfaces(toInterfaces(proxyClasses));
- enhancer.setSuperclass(getSuperclass(proxyClasses));
- enhancer.setCallbackFilter(callbackFilter);
- enhancer.setCallbacks(new Callback[]{new ObjectProviderDispatcher(targetProvider), new EqualsHandler(), new HashCodeHandler()});
- return enhancer.create();
- }
-
- public Object createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
- Class[] proxyClasses)
- {
- final Enhancer enhancer = new Enhancer();
- enhancer.setClassLoader(classLoader);
- enhancer.setInterfaces(toInterfaces(proxyClasses));
- enhancer.setSuperclass(getSuperclass(proxyClasses));
- enhancer.setCallbackFilter(callbackFilter);
- enhancer.setCallbacks(new Callback[]{new InterceptorBridge(target, interceptor), new EqualsHandler(), new HashCodeHandler()});
- return enhancer.create();
- }
-
- public Object createInvokerProxy(ClassLoader classLoader, Invoker invoker,
- Class[] proxyClasses)
- {
- final Enhancer enhancer = new Enhancer();
- enhancer.setClassLoader(classLoader);
- enhancer.setInterfaces(toInterfaces(proxyClasses));
- enhancer.setSuperclass(getSuperclass(proxyClasses));
- enhancer.setCallbackFilter(callbackFilter);
- enhancer.setCallbacks(new Callback[]{new InvokerBridge(invoker), new EqualsHandler(), new HashCodeHandler()});
- return enhancer.create();
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class InterceptorBridge implements net.sf.cglib.proxy.MethodInterceptor, Serializable
- {
- private final Interceptor inner;
- private final Object target;
-
- public InterceptorBridge(Object target, Interceptor inner)
- {
- this.inner = inner;
- this.target = target;
- }
-
- public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
- {
- return inner.intercept(new MethodProxyInvocation(target, method, args, methodProxy));
- }
- }
-
- private static class HashCodeHandler implements MethodInterceptor, Serializable
- {
- public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
- {
- return new Integer(System.identityHashCode(o));
- }
- }
-
- private static class EqualsHandler implements MethodInterceptor, Serializable
- {
- public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
- {
- return Boolean.valueOf(o == objects[0]);
- }
- }
-
-
- private static class InvokerBridge implements net.sf.cglib.proxy.InvocationHandler, Serializable
- {
- private final Invoker original;
-
- public InvokerBridge(Invoker original)
- {
- this.original = original;
- }
-
- public Object invoke(Object object, Method method, Object[] objects) throws Throwable
- {
- return original.invoke(object, method, objects);
- }
- }
-
- private static class MethodProxyInvocation implements Invocation, Serializable
- {
- private final MethodProxy methodProxy;
- private final Method method;
- private final Object[] args;
- private final Object target;
-
- public MethodProxyInvocation(Object target, Method method, Object[] args, MethodProxy methodProxy)
- {
- this.target = target;
- this.method = method;
- this.methodProxy = methodProxy;
- this.args = args;
- }
-
- public Method getMethod()
- {
- return method;
- }
-
- public Object[] getArguments()
- {
- return args;
- }
-
- public Object proceed() throws Throwable
- {
- return methodProxy.invoke(target, args);
- }
-
- public Object getProxy()
- {
- return target;
- }
- }
-
- private static class ObjectProviderDispatcher implements Dispatcher, Serializable
- {
- private final ObjectProvider delegateProvider;
-
- public ObjectProviderDispatcher(ObjectProvider delegateProvider)
- {
- this.delegateProvider = delegateProvider;
- }
-
- public Object loadObject()
- {
- return delegateProvider.getObject();
- }
- }
-
- private static class CglibProxyFactoryCallbackFilter implements CallbackFilter
- {
- public int accept(Method method)
- {
- if (isEqualsMethod(method))
- {
- return 1;
- }
- else if (isHashCode(method))
- {
- return 2;
- }
- else
- {
- return 0;
- }
- }
-
-
- }
-}
-
+/*
+ * 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.cglib;
+
+import net.sf.cglib.proxy.*;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.proxy2.*;
+import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+/**
+ * Cglib-based {@link ProxyFactory} implementation.
+ */
+public class CglibProxyFactory extends AbstractSubclassingProxyFactory
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private static CallbackFilter callbackFilter = new CglibProxyFactoryCallbackFilter();
+
+ //**********************************************************************************************************************
+ // ProxyFactory Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> targetProvider,
+ Class<?>... proxyClasses)
+ {
+ final Enhancer enhancer = new Enhancer();
+ enhancer.setClassLoader(classLoader);
+ enhancer.setInterfaces(toInterfaces(proxyClasses));
+ enhancer.setSuperclass(getSuperclass(proxyClasses));
+ enhancer.setCallbackFilter(callbackFilter);
+ enhancer.setCallbacks(new Callback[]{new ObjectProviderDispatcher(targetProvider), new EqualsHandler(), new HashCodeHandler()});
+ return (T) enhancer.create();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+ Class<?>... proxyClasses)
+ {
+ final Enhancer enhancer = new Enhancer();
+ enhancer.setClassLoader(classLoader);
+ enhancer.setInterfaces(toInterfaces(proxyClasses));
+ enhancer.setSuperclass(getSuperclass(proxyClasses));
+ enhancer.setCallbackFilter(callbackFilter);
+ enhancer.setCallbacks(new Callback[]{new InterceptorBridge(target, interceptor), new EqualsHandler(), new HashCodeHandler()});
+ return (T) enhancer.create();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker,
+ Class<?>... proxyClasses)
+ {
+ final Enhancer enhancer = new Enhancer();
+ enhancer.setClassLoader(classLoader);
+ enhancer.setInterfaces(toInterfaces(proxyClasses));
+ enhancer.setSuperclass(getSuperclass(proxyClasses));
+ enhancer.setCallbackFilter(callbackFilter);
+ enhancer.setCallbacks(new Callback[]{new InvokerBridge(invoker), new EqualsHandler(), new HashCodeHandler()});
+ return (T) enhancer.create();
+ }
+
+//**********************************************************************************************************************
+// Inner Classes
+//**********************************************************************************************************************
+
+ private static class CglibProxyFactoryCallbackFilter implements CallbackFilter
+ {
+ public int accept(Method method)
+ {
+ if (ProxyUtils.isEqualsMethod(method))
+ {
+ return 1;
+ }
+ else if (ProxyUtils.isHashCode(method))
+ {
+ return 2;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+
+ private static class EqualsHandler implements MethodInterceptor, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
+ {
+ return o == objects[0];
+ }
+ }
+
+ private static class HashCodeHandler implements MethodInterceptor, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
+ {
+ return System.identityHashCode(o);
+ }
+ }
+
+ private static class InterceptorBridge implements net.sf.cglib.proxy.MethodInterceptor, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Object target;
+ private final Interceptor inner;
+
+ public InterceptorBridge(Object target, Interceptor inner)
+ {
+ this.inner = inner;
+ this.target = target;
+ }
+
+ public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
+ {
+ return inner.intercept(new MethodProxyInvocation(object, target, method, args, methodProxy));
+ }
+ }
+
+ private static class InvokerBridge implements net.sf.cglib.proxy.InvocationHandler, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Invoker original;
+
+ public InvokerBridge(Invoker original)
+ {
+ this.original = original;
+ }
+
+ public Object invoke(Object object, Method method, Object[] objects) throws Throwable
+ {
+ return original.invoke(object, method, objects);
+ }
+ }
+
+ private static class MethodProxyInvocation implements Invocation, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Object proxy;
+ private final Object target;
+ private final Method method;
+ private final Object[] args;
+ private final MethodProxy methodProxy;
+
+ public MethodProxyInvocation(Object proxy, Object target, Method method, Object[] args, MethodProxy methodProxy)
+ {
+ this.proxy = proxy;
+ this.target = target;
+ this.method = method;
+ this.methodProxy = methodProxy;
+ this.args = ArrayUtils.clone(args);
+ }
+
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public Object[] getArguments()
+ {
+ return args;
+ }
+
+ public Object proceed() throws Throwable
+ {
+ return methodProxy.invoke(target, args);
+ }
+
+ public Object getProxy()
+ {
+ return proxy;
+ }
+ }
+
+ private static class ObjectProviderDispatcher implements Dispatcher, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final ObjectProvider<?> delegateProvider;
+
+ public ObjectProviderDispatcher(ObjectProvider<?> delegateProvider)
+ {
+ this.delegateProvider = delegateProvider;
+ }
+
+ public Object loadObject()
+ {
+ return delegateProvider.getObject();
+ }
+ }
+}
diff --git a/src/test/resources/log4j.properties b/cglib/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
similarity index 75%
copy from src/test/resources/log4j.properties
copy to cglib/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
index b981287..1fe9ac3 100644
--- a/src/test/resources/log4j.properties
+++ b/cglib/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
@@ -1,20 +1,17 @@
-#
-# 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.
-#
-log4j.rootLogger=DEBUG, console
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p (%c{1}) %3x - %m%n
\ No newline at end of file
+#
+# 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.
+#
+org.apache.commons.proxy2.cglib.CglibProxyFactory
\ No newline at end of file
diff --git a/cglib/src/site/markdown/index.md b/cglib/src/site/markdown/index.md
new file mode 100644
index 0000000..67a8584
--- /dev/null
+++ b/cglib/src/site/markdown/index.md
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+## Commons Proxy Cglib
+
+Provides the [CglibProxyFactory][] which uses the [cglib][] library
+to create proxy classes. This proxy factory is capable of proxying concrete
+non-`final` types and can thus be considered a *subclassing* proxy factory.
+
+[CglibProxyFactory]: apidocs/org/apache/commons/proxy2/cglib/CglibProxyFactory.html
+
+[cglib]: http://cglib.sourceforge.net/
diff --git a/src/test/java/org/apache/commons/proxy/exception/TestDelegateProviderException.java b/cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java
similarity index 81%
copy from src/test/java/org/apache/commons/proxy/exception/TestDelegateProviderException.java
copy to cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java
index 45af58c..cb2da8d 100644
--- a/src/test/java/org/apache/commons/proxy/exception/TestDelegateProviderException.java
+++ b/cglib/src/test/java/org/apache/commons/proxy2/cglib/CglibProxyFactoryTest.java
@@ -1,30 +1,31 @@
-/*
- * 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.proxy.exception;
-
-public class TestDelegateProviderException extends AbstractExceptionClassTestCase
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public TestDelegateProviderException()
- {
- super(ObjectProviderException.class);
- }
-}
\ No newline at end of file
+/*
+ * 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.cglib;
+
+import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;
+
+public class CglibProxyFactoryTest extends AbstractSubclassingProxyFactoryTestCase
+{
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ public CglibProxyFactoryTest()
+ {
+ }
+}
diff --git a/checkstyle.xml b/checkstyle.xml
deleted file mode 100644
index 696d8e6..0000000
--- a/checkstyle.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<!--
- ~ 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.
- -->
-<!DOCTYPE module PUBLIC
- "-//Puppy Crawl//DTD Check Configuration 1.1//EN"
- "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
-
-<!-- commons proxy customization of default Checkstyle behavior -->
-<module name="Checker">
- <property name="localeLanguage" value="en"/>
-
- <module name="TreeWalker">
- <!-- Verify that EVERY source file has the appropriate license -->
- <module name="Header">
- <property name="headerFile" value="${checkstyle.header.file}"/>
- </module>
-
- <!-- no tabs allowed in files -->
- <module name="TabCharacter"/>
-
- <!-- check sane import statements -->
- <module name="AvoidStarImport"/>
- <module name="RedundantImport"/>
- <module name="UnusedImports"/>
-
- <module name="LineLength">
- <property name="max" value="120"/>
- </module>
- </module>
-</module>
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..eb360da
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy2</artifactId>
+ <name>Commons Proxy Core</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>jmock</groupId>
+ <artifactId>jmock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/core/src/main/java/org/apache/commons/proxy2/DefaultProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/DefaultProxyFactory.java
new file mode 100644
index 0000000..0a6db83
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/DefaultProxyFactory.java
@@ -0,0 +1,128 @@
+/*
+ * 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;
+
+import java.util.Arrays;
+import java.util.ServiceLoader;
+
+/**
+ * {@link ProxyFactory} implementation that delegates to the first discovered
+ * {@link ProxyFactory} service provider that {@link #canProxy(Class...)}.
+ *
+ * @author Matt Benson
+ */
+class DefaultProxyFactory implements ProxyFactory {
+ /** Shared instance */
+ static final DefaultProxyFactory INSTANCE = new DefaultProxyFactory();
+
+ private static final ServiceLoader<ProxyFactory> SERVICES = ServiceLoader
+ .load(ProxyFactory.class);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean canProxy(Class<?>... proxyClasses) {
+ for (ProxyFactory proxyFactory : SERVICES) {
+ if (proxyFactory.canProxy(proxyClasses)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createDelegatorProxy(ObjectProvider<?> delegateProvider,
+ Class<?>... proxyClasses) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) getCapableProxyFactory(proxyClasses).createDelegatorProxy(
+ delegateProvider, proxyClasses);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createDelegatorProxy(ClassLoader classLoader,
+ ObjectProvider<?> delegateProvider, Class<?>... proxyClasses) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) getCapableProxyFactory(proxyClasses).createDelegatorProxy(
+ classLoader, delegateProvider, proxyClasses);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createInterceptorProxy(Object target, Interceptor interceptor,
+ Class<?>... proxyClasses) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) getCapableProxyFactory(proxyClasses).createInterceptorProxy(
+ target, interceptor, proxyClasses);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createInterceptorProxy(ClassLoader classLoader, Object target,
+ Interceptor interceptor, Class<?>... proxyClasses) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) getCapableProxyFactory(proxyClasses).createInterceptorProxy(
+ classLoader, target, interceptor, proxyClasses);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createInvokerProxy(Invoker invoker, Class<?>... proxyClasses) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) getCapableProxyFactory(proxyClasses).createInvokerProxy(
+ invoker, proxyClasses);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker,
+ Class<?>... proxyClasses) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) getCapableProxyFactory(proxyClasses).createInvokerProxy(
+ classLoader, invoker, proxyClasses);
+ return result;
+ }
+
+ private ProxyFactory getCapableProxyFactory(Class<?>... proxyClasses) {
+ for (ProxyFactory proxyFactory : SERVICES) {
+ if (proxyFactory.canProxy(proxyClasses)) {
+ return proxyFactory;
+ }
+ }
+ throw new IllegalArgumentException("Could not proxy "
+ + Arrays.toString(proxyClasses));
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/Interceptor.java b/core/src/main/java/org/apache/commons/proxy2/Interceptor.java
similarity index 82%
rename from src/main/java/org/apache/commons/proxy/Interceptor.java
rename to core/src/main/java/org/apache/commons/proxy2/Interceptor.java
index ecb4fe0..5b2c668 100644
--- a/src/main/java/org/apache/commons/proxy/Interceptor.java
+++ b/core/src/main/java/org/apache/commons/proxy2/Interceptor.java
@@ -1,35 +1,41 @@
-/*
- * 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.proxy;
-
-import java.io.Serializable;
-
-/**
- * "Intercepts" a method invocation.
- *
- * @author James Carman
- * @since 1.0
- */
-public interface Interceptor extends Serializable
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public Object intercept( Invocation invocation ) throws Throwable;
-}
+/*
+ * 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;
+
+import java.io.Serializable;
+
+/**
+ * "Intercepts" a method invocation.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public interface Interceptor extends Serializable
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ /**
+ * Intercept the specified {@link Invocation}.
+ * @param invocation
+ * @return return value of the method
+ * @throws Throwable
+ */
+ Object intercept( Invocation invocation ) throws Throwable;
+}
diff --git a/src/main/java/org/apache/commons/proxy/Invocation.java b/core/src/main/java/org/apache/commons/proxy2/Invocation.java
similarity index 89%
rename from src/main/java/org/apache/commons/proxy/Invocation.java
rename to core/src/main/java/org/apache/commons/proxy2/Invocation.java
index 571790e..0c0c60b 100644
--- a/src/main/java/org/apache/commons/proxy/Invocation.java
+++ b/core/src/main/java/org/apache/commons/proxy2/Invocation.java
@@ -1,63 +1,63 @@
-/*
- * 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.proxy;
-
-import java.lang.reflect.Method;
-
-/**
- * Represents a method invocation.
- *
- * @author James Carman
- * @since 1.0
- */
-public interface Invocation
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * Returns the arguments being passed to this method invocation. Changes in the elements of this array will be
- * propagated to the recipient of this invocation.
- *
- * @return the arguments being passed to this method invocation
- */
- public Object[] getArguments();
-
- /**
- * Returns the method being called.
- *
- * @return the method being called
- */
- public Method getMethod();
-
- /**
- * Returns the proxy object on which this invocation was invoked.
- *
- * @return the proxy object on which this invocation was invoked
- */
- public Object getProxy();
-
- /**
- * Called in order to let the invocation proceed.
- *
- * @return the return value of the invocation
- * @throws Throwable any exception or error that was thrown as a result of this invocation
- */
- public Object proceed() throws Throwable;
-}
+/*
+ * 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;
+
+import java.lang.reflect.Method;
+
+/**
+ * Method invocation for use by an {@link Interceptor}.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public interface Invocation
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ /**
+ * Returns the arguments being passed to this method invocation. Changes in the elements of this array will be
+ * propagated to the recipient of this invocation.
+ *
+ * @return the arguments being passed to this method invocation
+ */
+ Object[] getArguments();
+
+ /**
+ * Returns the method being called.
+ *
+ * @return the method being called
+ */
+ Method getMethod();
+
+ /**
+ * Returns the proxy object on which this invocation was invoked.
+ *
+ * @return the proxy object on which this invocation was invoked
+ */
+ Object getProxy();
+
+ /**
+ * Called in order to let the invocation proceed.
+ *
+ * @return the return value of the invocation
+ * @throws Throwable any exception or error that was thrown as a result of this invocation
+ */
+ Object proceed() throws Throwable;
+}
diff --git a/src/main/java/org/apache/commons/proxy/Invoker.java b/core/src/main/java/org/apache/commons/proxy2/Invoker.java
similarity index 87%
rename from src/main/java/org/apache/commons/proxy/Invoker.java
rename to core/src/main/java/org/apache/commons/proxy2/Invoker.java
index ba90110..aa5689c 100644
--- a/src/main/java/org/apache/commons/proxy/Invoker.java
+++ b/core/src/main/java/org/apache/commons/proxy2/Invoker.java
@@ -1,46 +1,46 @@
-/*
- * 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.proxy;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-/**
- * An invoker is responsible for handling a method invocation.
- *
- * @author James Carman
- * @since 1.0
- */
-public interface Invoker extends Serializable
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * "Invokes" the method. Implementation should throw a {@link org.apache.commons.proxy.exception.InvokerException}
- * if problems arise while trying to invoke the method.
- *
- * @param proxy the proxy object
- * @param method the method being invoked
- * @param arguments the arguments
- * @return the return value
- * @throws Throwable thrown by the implementation
- */
- public Object invoke( Object proxy, Method method, Object[] arguments ) throws Throwable;
-}
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+/**
+ * An invoker is responsible for handling a method invocation.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public interface Invoker extends Serializable
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ /**
+ * "Invokes" the method. Implementation should throw a {@link org.apache.commons.proxy2.exception.InvokerException}
+ * if problems arise while trying to invoke the method.
+ *
+ * @param proxy the proxy2 object
+ * @param method the method being invoked
+ * @param arguments the arguments
+ * @return the return value
+ * @throws Throwable thrown by the implementation
+ */
+ Object invoke( Object proxy, Method method, Object[] arguments ) throws Throwable;
+}
diff --git a/src/main/java/org/apache/commons/proxy/ObjectProvider.java b/core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java
similarity index 86%
rename from src/main/java/org/apache/commons/proxy/ObjectProvider.java
rename to core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java
index 0581ee3..ea3ce01 100644
--- a/src/main/java/org/apache/commons/proxy/ObjectProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/ObjectProvider.java
@@ -1,41 +1,40 @@
-/*
- * 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.proxy;
-
-/**
- * Provides an object to a delegating proxy.
- *
- * @author James Carman
- * @since 1.0
- */
-public interface ObjectProvider
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * Returns an object. Implementing classes should throw a
- * {@link org.apache.commons.proxy.exception.ObjectProviderException} if any problems arise while
- * constructing/finding the object.
- *
- * @return the object on which the method should be called
- */
- public Object getObject();
-}
-
+/*
+ * 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;
+
+/**
+ * Provides an object to a delegating proxy.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public interface ObjectProvider<T>
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ /**
+ * Returns an object. Implementing classes should throw a
+ * {@link org.apache.commons.proxy2.exception.ObjectProviderException} if any problems arise while
+ * constructing/finding the object.
+ *
+ * @return the object on which the method should be called
+ */
+ T getObject();
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java
new file mode 100644
index 0000000..a3e3ea8
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/ProxyFactory.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+/**
+ * ProxyFactory interface.
+ * @since 2.0
+ */
+public interface ProxyFactory
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ /**
+ * Learn whether this {@link ProxyFactory} is capable of creating a proxy for the specified set of classes.
+ *
+ * @param proxyClasses the proxy2 classes
+ * @return boolean
+ */
+ boolean canProxy( Class<?>... proxyClasses );
+
+ /**
+ * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be
+ * generated using the current thread's "context class loader."
+ *
+ * @param delegateProvider the delegate provider
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which delegates to the object provided by the target object provider
+ */
+ <T> T createDelegatorProxy( ObjectProvider<?> delegateProvider, Class<?>... proxyClasses );
+
+ /**
+ * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>.
+ *
+ * @param classLoader the class loader to use when generating the proxy
+ * @param delegateProvider the delegate provider
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which delegates to the object provided by the target <code>delegateProvider>
+ */
+ <T> T createDelegatorProxy( ClassLoader classLoader, ObjectProvider<?> delegateProvider,
+ Class<?>... proxyClasses );
+
+ /**
+ * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."
+ *
+ * @param target the target object
+ * @param interceptor the method interceptor
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object.
+ */
+ <T> T createInterceptorProxy( Object target, Interceptor interceptor,
+ Class<?>... proxyClasses );
+
+ /**
+ * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object.
+ *
+ * @param classLoader the class loader to use when generating the proxy
+ * @param target the target object
+ * @param interceptor the method interceptor
+ * @param proxyClasses the interfaces that the proxy should implement.
+ * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object.
+ */
+ <T> T createInterceptorProxy( ClassLoader classLoader, Object target, Interceptor interceptor,
+ Class<?>... proxyClasses );
+
+ /**
+ * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be
+ * generated using the current thread's "context class loader."
+ *
+ * @param invoker the invoker
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
+ */
+ <T> T createInvokerProxy( Invoker invoker, Class<?>... proxyClasses );
+
+ /**
+ * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations.
+ *
+ * @param classLoader the class loader to use when generating the proxy
+ * @param invoker the invoker
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
+ */
+ <T> T createInvokerProxy( ClassLoader classLoader, Invoker invoker,
+ Class<?>... proxyClasses );
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java b/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java
new file mode 100644
index 0000000..dddab95
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/ProxyUtils.java
@@ -0,0 +1,192 @@
+/*
+ * 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;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides some helpful proxy utility methods.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public final class ProxyUtils
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ public static final Object[] EMPTY_ARGUMENTS = new Object[0];
+ public static final Class<?>[] EMPTY_ARGUMENT_TYPES = new Class[0];
+ private static final Map<Class<?>, Class<?>> WRAPPER_CLASS_MAP = new HashMap<Class<?>, Class<?>>();
+ private static final Map<Class<?>, Object> NULL_VALUE_MAP = new HashMap<Class<?>, Object>();
+
+//**********************************************************************************************************************
+// Static Methods
+//**********************************************************************************************************************
+
+ static
+ {
+ WRAPPER_CLASS_MAP.put(Integer.TYPE, Integer.class);
+ WRAPPER_CLASS_MAP.put(Character.TYPE, Character.class);
+ WRAPPER_CLASS_MAP.put(Boolean.TYPE, Boolean.class);
+ WRAPPER_CLASS_MAP.put(Short.TYPE, Short.class);
+ WRAPPER_CLASS_MAP.put(Long.TYPE, Long.class);
+ WRAPPER_CLASS_MAP.put(Float.TYPE, Float.class);
+ WRAPPER_CLASS_MAP.put(Double.TYPE, Double.class);
+ WRAPPER_CLASS_MAP.put(Byte.TYPE, Byte.class);
+ }
+
+ static
+ {
+ NULL_VALUE_MAP.put(Integer.TYPE, 0);
+ NULL_VALUE_MAP.put(Long.TYPE, (long) 0);
+ NULL_VALUE_MAP.put(Short.TYPE, (short) 0);
+ NULL_VALUE_MAP.put(Byte.TYPE, (byte) 0);
+ NULL_VALUE_MAP.put(Float.TYPE, 0.0f);
+ NULL_VALUE_MAP.put(Double.TYPE, 0.0);
+ NULL_VALUE_MAP.put(Character.TYPE, (char) 0);
+ NULL_VALUE_MAP.put(Boolean.TYPE, Boolean.FALSE);
+ }
+
+ /**
+ * <p>Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its
+ * superclasses.</p>
+ * <p/>
+ * <p>The order is determined by looking through each interface in turn as declared in the source file and following
+ * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order
+ * is maintained.</p>
+ * <p/>
+ * <b>Note</b>: Implementation of this method was "borrowed" from
+ * <a href="http://commons.apache.org/lang/">Apache Commons Lang</a> to avoid a dependency.</p>
+ *
+ * @param cls the class to look up, may be <code>null</code>
+ * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its
+ * superclasses or <code>null</code> if input class is null.
+ */
+ public static Class<?>[] getAllInterfaces(Class<?> cls)
+ {
+ final List<Class<?>> interfaces = getAllInterfacesImpl(cls, new LinkedList<Class<?>>());
+ return interfaces == null ? null : (Class[]) interfaces.toArray(new Class[interfaces.size()]);
+ }
+
+ private static List<Class<?>> getAllInterfacesImpl(final Class<?> cls, List<Class<?>> list)
+ {
+ if (cls == null)
+ {
+ return null;
+ }
+ Class<?> currentClass = cls;
+ while (currentClass != null)
+ {
+ Class<?>[] interfaces = currentClass.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++)
+ {
+ if (!list.contains(interfaces[i]))
+ {
+ list.add(interfaces[i]);
+ }
+ getAllInterfacesImpl(interfaces[i], list);
+ }
+ currentClass = currentClass.getSuperclass();
+ }
+ return list;
+ }
+
+ /**
+ * Returns the class name as you would expect to see it in Java code.
+ * <p/>
+ * <b>Examples:</b> <ul> <li>getJavaClassName( Object[].class ) == "Object[]"</li> <li>getJavaClassName(
+ * Object[][].class ) == "Object[][]"</li> <li>getJavaClassName( Integer.TYPE ) == "int"</li> </p>
+ *
+ * @param clazz the class
+ * @return the class' name as you would expect to see it in Java code
+ */
+ public static String getJavaClassName(Class<?> clazz)
+ {
+ if (clazz.isArray())
+ {
+ return getJavaClassName(clazz.getComponentType()) + "[]";
+ }
+ return clazz.getName();
+ }
+
+ /**
+ * Returns the wrapper class for the given primitive type.
+ *
+ * @param primitiveType the primitive type
+ * @return the wrapper class
+ */
+ public static Class<?> getWrapperClass(Class<?> primitiveType)
+ {
+ return WRAPPER_CLASS_MAP.get(primitiveType);
+ }
+
+ /**
+ * Returns the proper "null value" as specified by the Java language.
+ *
+ * @param type the type
+ * @return the null value
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T nullValue(Class<T> type)
+ {
+ return (T) NULL_VALUE_MAP.get(type);
+ }
+
+ /**
+ * Learn whether the specified method is/overrides {@link Object#equals(Object)}.
+ * @param method to compare
+ * @return <code>true</code> for a method with signature <code>boolean equals(Object)</code>
+ */
+ public static boolean isEqualsMethod(Method method)
+ {
+ return "equals".equals(method.getName()) &&
+ Boolean.TYPE.equals(method.getReturnType()) &&
+ method.getParameterTypes().length == 1 &&
+ Object.class.equals(method.getParameterTypes()[0]);
+ }
+
+ /**
+ * Learn whether the specified method is/overrides {@link Object#hashCode()}.
+ * @param method to compare
+ * @return true for a method with signature <code>int hashCode()</code>
+ */
+ public static boolean isHashCode(Method method)
+ {
+ return "hashCode".equals(method.getName()) &&
+ Integer.TYPE.equals(method.getReturnType()) &&
+ method.getParameterTypes().length == 0;
+ }
+
+ /**
+ * Get a {@link ProxyFactory} that delegates to discoverable {@link ProxyFactory} service providers.
+ * @return {@link ProxyFactory}
+ */
+ public static ProxyFactory proxyFactory() {
+ return DefaultProxyFactory.INSTANCE;
+ }
+
+ private ProxyUtils() {
+ // Hiding constructor in utility class!
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java b/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java
new file mode 100644
index 0000000..a747968
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/exception/InvokerException.java
@@ -0,0 +1,69 @@
+/*
+ * 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.exception;
+
+/**
+ * To be used by an {@link org.apache.commons.proxy2.Invoker} when they encounter an error.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class InvokerException extends RuntimeException
+{
+ /** Serialization version */
+ private static final long serialVersionUID = -1L;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new InvokerException instance.
+ */
+ public InvokerException()
+ {
+ }
+
+ /**
+ * Create a new InvokerException instance.
+ * @param message
+ */
+ public InvokerException( String message )
+ {
+ super(message);
+ }
+
+ /**
+ * Create a new InvokerException instance.
+ * @param cause
+ */
+ public InvokerException( Throwable cause )
+ {
+ super(cause);
+ }
+
+ /**
+ * Create a new InvokerException instance.
+ * @param message
+ * @param cause
+ */
+ public InvokerException( String message, Throwable cause )
+ {
+ super(message, cause);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java b/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java
new file mode 100644
index 0000000..7b956ca
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/exception/ObjectProviderException.java
@@ -0,0 +1,70 @@
+/*
+ * 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.exception;
+
+/**
+ * {@link org.apache.commons.proxy2.ObjectProvider} implementations should throw this exception type to indicate that
+ * there was a problem creating/finding the object.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class ObjectProviderException extends RuntimeException
+{
+ /** Serialization version */
+ private static final long serialVersionUID = -1L;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new ObjectProviderException instance.
+ */
+ public ObjectProviderException()
+ {
+ }
+
+ /**
+ * Create a new ObjectProviderException instance.
+ * @param message
+ */
+ public ObjectProviderException( String message )
+ {
+ super(message);
+ }
+
+ /**
+ * Create a new ObjectProviderException instance.
+ * @param cause
+ */
+ public ObjectProviderException( Throwable cause )
+ {
+ super(cause);
+ }
+
+ /**
+ * Create a new ObjectProviderException instance.
+ * @param message
+ * @param cause
+ */
+ public ObjectProviderException( String message, Throwable cause )
+ {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/exception/ProxyFactoryException.java b/core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java
similarity index 62%
rename from src/main/java/org/apache/commons/proxy/exception/ProxyFactoryException.java
rename to core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java
index 073d2f4..de673ad 100644
--- a/src/main/java/org/apache/commons/proxy/exception/ProxyFactoryException.java
+++ b/core/src/main/java/org/apache/commons/proxy2/exception/ProxyFactoryException.java
@@ -1,52 +1,70 @@
-/*
- * 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.proxy.exception;
-
-/**
- * A runtime exception type to be used by {@link org.apache.commons.proxy.ProxyFactory proxy factories} when a problem
- * occurs.
- *
- * @author James Carman
- * @since 1.0
- */
-public class ProxyFactoryException extends RuntimeException
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ProxyFactoryException()
- {
- }
-
- public ProxyFactoryException( String message )
- {
- super(message);
- }
-
- public ProxyFactoryException( Throwable cause )
- {
- super(cause);
- }
-
- public ProxyFactoryException( String message, Throwable cause )
- {
- super(message, cause);
- }
-}
-
+/*
+ * 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.exception;
+
+/**
+ * A runtime exception type to be used by {@link org.apache.commons.proxy2.ProxyFactory proxy factories} when a problem
+ * occurs.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class ProxyFactoryException extends RuntimeException
+{
+ /** Serialization version */
+ private static final long serialVersionUID = -1L;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new ProxyFactoryException instance.
+ */
+ public ProxyFactoryException()
+ {
+ }
+
+ /**
+ * Create a new ProxyFactoryException instance.
+ * @param message
+ */
+ public ProxyFactoryException( String message )
+ {
+ super(message);
+ }
+
+ /**
+ * Create a new ProxyFactoryException instance.
+ * @param cause
+ */
+ public ProxyFactoryException( Throwable cause )
+ {
+ super(cause);
+ }
+
+ /**
+ * Create a new ProxyFactoryException instance.
+ * @param message
+ * @param cause
+ */
+ public ProxyFactoryException( String message, Throwable cause )
+ {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java
similarity index 77%
rename from src/main/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java
rename to core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java
index 99ed300..aa777d2 100644
--- a/src/main/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyClassGenerator.java
@@ -1,79 +1,71 @@
-/*
- * 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.proxy.factory.util;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A useful superclass for {@link ProxyClassGenerator} implementations.
- *
- * @author James Carman
- * @since 1.0
- */
-public abstract class AbstractProxyClassGenerator implements ProxyClassGenerator
-{
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- /**
- * Returns all methods that a proxy class must implement from the proxy interfaces. This method makes sure there
- * are no method signature clashes. For methods with the same signature (name and parameter types), the one
- * encountered first will be returned in the result. Final methods are also excluded from the result.
- *
- * @param proxyClasses the interfaces the proxy class must implement
- * @return all methods that the proxy class must implement
- */
- public static Method[] getImplementationMethods( Class[] proxyClasses )
- {
- final Map signatureMethodMap = new HashMap();
- final Set finalizedSignatures = new HashSet();
- for( int i = 0; i < proxyClasses.length; i++ )
- {
- Class proxyInterface = proxyClasses[i];
- final Method[] methods = proxyInterface.getMethods();
- for( int j = 0; j < methods.length; j++ )
- {
- final MethodSignature signature = new MethodSignature(methods[j]);
- if( Modifier.isFinal(methods[j].getModifiers()) )
- {
- finalizedSignatures.add(signature);
- }
- else if( !signatureMethodMap.containsKey(signature) )
- {
- signatureMethodMap.put(signature, methods[j]);
- }
- }
- }
- final Collection resultingMethods = signatureMethodMap.values();
- for( Iterator i = finalizedSignatures.iterator(); i.hasNext(); )
- {
- MethodSignature signature = ( MethodSignature ) i.next();
- resultingMethods.remove(signatureMethodMap.get(signature));
- }
- return ( Method[] ) resultingMethods.toArray(new Method[resultingMethods.size()]);
- }
-}
-
+/*
+ * 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.impl;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * A useful superclass for {@link ProxyClassGenerator} implementations.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public abstract class AbstractProxyClassGenerator implements ProxyClassGenerator
+{
+//**********************************************************************************************************************
+// Static Methods
+//**********************************************************************************************************************
+
+ /**
+ * Returns all methods that a proxy class must implement from the proxy interfaces. This method makes sure there
+ * are no method signature clashes. For methods with the same signature (name and parameter types), the one
+ * encountered first will be returned in the result. Final methods are also excluded from the result.
+ *
+ * @param proxyClasses the interfaces the proxy class must implement
+ * @return all methods that the proxy class must implement
+ */
+ public static Method[] getImplementationMethods( Class<?>[] proxyClasses )
+ {
+ final Map<MethodSignature, Method> signatureMethodMap = new HashMap<MethodSignature, Method>();
+ final Set<MethodSignature> finalizedSignatures = new HashSet<MethodSignature>();
+ for( int i = 0; i < proxyClasses.length; i++ )
+ {
+ Class<?> proxyInterface = proxyClasses[i];
+ final Method[] methods = proxyInterface.getMethods();
+ for( int j = 0; j < methods.length; j++ )
+ {
+ final MethodSignature signature = new MethodSignature(methods[j]);
+ if( Modifier.isFinal(methods[j].getModifiers()) )
+ {
+ finalizedSignatures.add(signature);
+ }
+ else if( !signatureMethodMap.containsKey(signature) )
+ {
+ signatureMethodMap.put(signature, methods[j]);
+ }
+ }
+ }
+ final Collection<Method> resultingMethods = signatureMethodMap.values();
+ for (MethodSignature signature : finalizedSignatures) {
+ resultingMethods.remove(signatureMethodMap.get(signature));
+ }
+ return resultingMethods.toArray(new Method[resultingMethods.size()]);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java
new file mode 100644
index 0000000..253d98c
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractProxyFactory.java
@@ -0,0 +1,94 @@
+/*
+ * 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.impl;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyFactory;
+
+/**
+ * Base abstract {@link ProxyFactory} implementation, primarily providing
+ * implementations of the interface methods that are typically convenience
+ * constructs over the other methods.
+ */
+public abstract class AbstractProxyFactory implements ProxyFactory
+{
+ /**
+ * Returns true if all <code>proxyClasses</code> are interfaces.
+ *
+ * @param proxyClasses the proxy classes
+ * @return true if all <code>proxyClasses</code> are interfaces
+ */
+ public boolean canProxy( Class<?>... proxyClasses )
+ {
+ for( Class<?> proxyClass : proxyClasses )
+ {
+ if( !proxyClass.isInterface() )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be
+ * generated using the current thread's "context class loader."
+ *
+ * @param delegateProvider the delegate provider
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which delegates to the object provided by the target object provider
+ */
+ public <T> T createDelegatorProxy( ObjectProvider<?> delegateProvider, Class<?>... proxyClasses )
+ {
+ return createDelegatorProxy(Thread.currentThread().getContextClassLoader(), delegateProvider, proxyClasses);
+ }
+
+ /**
+ * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."
+ *
+ * @param target the target object
+ * @param interceptor the method interceptor
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object.
+ */
+ public <T> T createInterceptorProxy( Object target, Interceptor interceptor,
+ Class<?>... proxyClasses )
+ {
+ return createInterceptorProxy(Thread.currentThread().getContextClassLoader(), target, interceptor,
+ proxyClasses);
+ }
+
+ /**
+ * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be
+ * generated using the current thread's "context class loader."
+ *
+ * @param invoker the invoker
+ * @param proxyClasses the interfaces that the proxy should implement
+ * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
+ */
+ public <T> T createInvokerProxy( Invoker invoker, Class<?>... proxyClasses )
+ {
+ return createInvokerProxy(Thread.currentThread().getContextClassLoader(), invoker,
+ proxyClasses);
+ }
+
+}
diff --git a/src/main/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java
similarity index 61%
rename from src/main/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java
rename to core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java
index 99df972..b87499b 100644
--- a/src/main/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/AbstractSubclassingProxyFactory.java
@@ -1,169 +1,145 @@
-/*
- * 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.proxy.factory.util;
-
-import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.exception.ProxyFactoryException;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * A useful superclass for a {@link ProxyFactory} which supports subclassing rather than merely implementing interfaces.
- *
- * @author James Carman
- * @since 1.0
- */
-public abstract class AbstractSubclassingProxyFactory extends ProxyFactory
-{
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- /**
- * Returns either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
- * class from <code>proxyClasses</code>.
- *
- * @param proxyClasses the proxy classes
- * @return either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
- * class from <code>proxyClasses</code>
- * @throws ProxyFactoryException if multiple non-interface classes are contained in <code>proxyClasses</code> or any
- * of the non-interface classes are final
- */
- public static Class getSuperclass( Class[] proxyClasses )
- {
- final Class[] superclasses = toNonInterfaces(proxyClasses);
- switch( superclasses.length )
- {
- case 0:
- return Object.class;
- case 1:
- final Class superclass = superclasses[0];
- if( Modifier.isFinal(superclass.getModifiers()) )
- {
- throw new ProxyFactoryException(
- "Proxy class cannot extend " + superclass.getName() + " as it is final.");
- }
- if( !hasSuitableDefaultConstructor(superclass) )
- {
- throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName() +
- ", because it has no visible \"default\" constructor.");
- }
- return superclass;
- default:
- final StringBuffer errorMessage = new StringBuffer("Proxy class cannot extend ");
- for( int i = 0; i < superclasses.length; i++ )
- {
- Class c = superclasses[i];
- errorMessage.append(c.getName());
- if( i != superclasses.length - 1 )
- {
- errorMessage.append(", ");
- }
- }
- errorMessage.append("; multiple inheritance not allowed.");
- throw new ProxyFactoryException(errorMessage.toString());
- }
- }
-
- private static boolean hasSuitableDefaultConstructor( Class superclass )
- {
- final Constructor[] declaredConstructors = superclass.getDeclaredConstructors();
- for( int i = 0; i < declaredConstructors.length; i++ )
- {
- Constructor constructor = declaredConstructors[i];
- if( constructor.getParameterTypes().length == 0 && ( Modifier.isPublic(constructor.getModifiers()) ||
- Modifier.isProtected(constructor.getModifiers()) ) )
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the <code>proxyClasses</code> transformed into an array of only the interface classes.
- * <p/>
- * <b>Note</b>: This class will append {@link Serializable} to the end of the list if it's
- * not found!
- *
- * @param proxyClasses the proxy classes
- * @return the <code>proxyClasses</code> transformed into an array of only the interface classes
- */
- protected static Class[] toInterfaces( Class[] proxyClasses )
- {
- final Collection interfaces = new LinkedList();
- boolean serializableFound = false;
- for( int i = 0; i < proxyClasses.length; i++ )
- {
- Class proxyInterface = proxyClasses[i];
- if( proxyInterface.isInterface() )
- {
- interfaces.add(proxyInterface);
- }
- serializableFound |= ( Serializable.class.equals(proxyInterface) );
- }
- if( !serializableFound )
- {
- interfaces.add(Serializable.class);
- }
- return ( Class[] ) interfaces.toArray(new Class[interfaces.size()]);
- }
-
- private static Class[] toNonInterfaces( Class[] proxyClasses )
- {
- final List superclasses = new LinkedList();
- for( int i = 0; i < proxyClasses.length; i++ )
- {
- Class proxyClass = proxyClasses[i];
- if( !proxyClass.isInterface() )
- {
- superclasses.add(proxyClass);
- }
- }
- return ( Class[] ) superclasses.toArray(new Class[superclasses.size()]);
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * Returns true if a suitable superclass can be found, given the desired <code>proxyClasses</code>.
- *
- * @param proxyClasses the proxy classes
- * @return true if a suitable superclass can be found, given the desired <code>proxyClasses</code>
- */
- public boolean canProxy( Class[] proxyClasses )
- {
- try
- {
- getSuperclass(proxyClasses);
- return true;
- }
- catch( ProxyFactoryException e )
- {
- return false;
- }
- }
-}
-
+package org.apache.commons.proxy2.impl;
+
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Parent {@link AbstractProxyFactory} for implementations that permit the generation of
+ * proxies with a specific inheritance hierarchy.
+ */
+public abstract class AbstractSubclassingProxyFactory extends AbstractProxyFactory
+{
+//**********************************************************************************************************************
+// ProxyFactory Implementation
+//**********************************************************************************************************************
+
+ /**
+ * Returns true if a suitable superclass can be found, given the desired <code>proxyClasses</code>.
+ *
+ * @param proxyClasses the proxy classes
+ * @return true if a suitable superclass can be found, given the desired <code>proxyClasses</code>
+ */
+ public boolean canProxy( Class<?>... proxyClasses )
+ {
+ try
+ {
+ getSuperclass(proxyClasses);
+ return true;
+ }
+ catch( ProxyFactoryException e )
+ {
+ return false;
+ }
+ }
+
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ private static boolean hasSuitableDefaultConstructor( Class<?> superclass )
+ {
+ final Constructor<?>[] declaredConstructors = superclass.getDeclaredConstructors();
+ for( int i = 0; i < declaredConstructors.length; i++ )
+ {
+ Constructor<?> constructor = declaredConstructors[i];
+ if( constructor.getParameterTypes().length == 0 && ( Modifier.isPublic(constructor.getModifiers()) ||
+ Modifier.isProtected(constructor.getModifiers()) ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Class<?>[] toNonInterfaces( Class<?>[] proxyClasses )
+ {
+ final Set<Class<?>> superclasses = new LinkedHashSet<Class<?>>();
+ for (Class<?> proxyClass : proxyClasses)
+ {
+ if( !proxyClass.isInterface())
+ {
+ superclasses.add(proxyClass);
+ }
+ }
+ return superclasses.toArray(new Class[superclasses.size()]);
+ }
+
+ /**
+ * Returns the <code>proxyClasses</code> transformed into an array of only the interface classes.
+ * <p/>
+ * <b>Note</b>: This class will append {@link Serializable} to the end of the list if it's
+ * not found!
+ *
+ * @param proxyClasses the proxy classes
+ * @return the <code>proxyClasses</code> transformed into an array of only the interface classes
+ */
+ protected static Class<?>[] toInterfaces( Class<?>[] proxyClasses )
+ {
+ final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
+ boolean serializableFound = false;
+ for (Class<?> proxyClass : proxyClasses)
+ {
+ if( proxyClass.isInterface() )
+ {
+ interfaces.add(proxyClass);
+ }
+ serializableFound |= ( Serializable.class.equals(proxyClass) );
+ }
+ if( !serializableFound )
+ {
+ interfaces.add(Serializable.class);
+ }
+ return ( Class[] ) interfaces.toArray(new Class[interfaces.size()]);
+ }
+
+ /**
+ * Returns either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
+ * class from <code>proxyClasses</code>.
+ *
+ * @param proxyClasses the proxy classes
+ * @return either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
+ * class from <code>proxyClasses</code>
+ * @throws ProxyFactoryException if multiple non-interface classes are contained in <code>proxyClasses</code> or any
+ * of the non-interface classes are final
+ */
+ public static Class<?> getSuperclass( Class<?>[] proxyClasses )
+ {
+ final Class<?>[] superclasses = toNonInterfaces(proxyClasses);
+ switch( superclasses.length )
+ {
+ case 0:
+ return Object.class;
+ case 1:
+ final Class<?> superclass = superclasses[0];
+ if( Modifier.isFinal(superclass.getModifiers()) )
+ {
+ throw new ProxyFactoryException(
+ "Proxy class cannot extend " + superclass.getName() + " as it is final.");
+ }
+ if( !hasSuitableDefaultConstructor(superclass) )
+ {
+ throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName() +
+ ", because it has no visible \"default\" constructor.");
+ }
+ return superclass;
+ default:
+ final StringBuilder errorMessage = new StringBuilder("Proxy class cannot extend ");
+ for( int i = 0; i < superclasses.length; i++ )
+ {
+ Class<?> c = superclasses[i];
+ errorMessage.append(c.getName());
+ if( i != superclasses.length - 1 )
+ {
+ errorMessage.append(", ");
+ }
+ }
+ errorMessage.append("; multiple inheritance not allowed.");
+ throw new ProxyFactoryException(errorMessage.toString());
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java b/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java
new file mode 100644
index 0000000..05cad71
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/MethodSignature.java
@@ -0,0 +1,263 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.text.ParsePosition;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * A class for capturing the signature of a method (its name and parameter types).
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class MethodSignature implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private static final Map<Class<?>, Character> PRIMITIVE_ABBREVIATIONS;
+ private static final Map<Character, Class<?>> REVERSE_ABBREVIATIONS;
+ static
+ {
+ final Map<Class<?>, Character> primitiveAbbreviations = new HashMap<Class<?>, Character>();
+ primitiveAbbreviations.put(Boolean.TYPE, Character.valueOf('Z'));
+ primitiveAbbreviations.put(Byte.TYPE, Character.valueOf('B'));
+ primitiveAbbreviations.put(Short.TYPE, Character.valueOf('S'));
+ primitiveAbbreviations.put(Integer.TYPE, Character.valueOf('I'));
+ primitiveAbbreviations.put(Character.TYPE, Character.valueOf('C'));
+ primitiveAbbreviations.put(Long.TYPE, Character.valueOf('J'));
+ primitiveAbbreviations.put(Float.TYPE, Character.valueOf('F'));
+ primitiveAbbreviations.put(Double.TYPE, Character.valueOf('D'));
+ primitiveAbbreviations.put(Void.TYPE, Character.valueOf('V'));
+ final Map<Character, Class<?>> reverseAbbreviations = new HashMap<Character, Class<?>>();
+ for (Map.Entry<Class<?>, Character> e : primitiveAbbreviations.entrySet())
+ {
+ reverseAbbreviations.put(e.getValue(), e.getKey());
+ }
+ PRIMITIVE_ABBREVIATIONS = Collections.unmodifiableMap(primitiveAbbreviations);
+ REVERSE_ABBREVIATIONS = Collections.unmodifiableMap(reverseAbbreviations);
+ }
+
+ private static void appendTo(StringBuilder buf, Class<?> type)
+ {
+ if (type.isPrimitive())
+ {
+ buf.append(PRIMITIVE_ABBREVIATIONS.get(type));
+ }
+ else if (type.isArray())
+ {
+ buf.append('[');
+ appendTo(buf, type.getComponentType());
+ }
+ else
+ {
+ buf.append('L').append(type.getName().replace('.', '/')).append(';');
+ }
+ }
+
+ private static class SignaturePosition extends ParsePosition
+ {
+ SignaturePosition() {
+ super(0);
+ }
+
+ SignaturePosition next()
+ {
+ return plus(1);
+ }
+
+ SignaturePosition plus(int addend)
+ {
+ setIndex(getIndex() + addend);
+ return this;
+ }
+ }
+
+ private static Pair<String, Class<?>[]> parse(String internal)
+ {
+ Validate.notBlank(internal, "Cannot parse blank method signature");
+ final SignaturePosition pos = new SignaturePosition();
+ int lparen = internal.indexOf('(', pos.getIndex());
+ Validate.isTrue(lparen > 0, "Method signature \"%s\" requires parentheses", internal);
+ final String name = internal.substring(0, lparen).trim();
+ Validate.notBlank(name, "Method signature \"%s\" has blank name", internal);
+
+ pos.setIndex(lparen + 1);
+
+ boolean complete = false;
+ final List<Class<?>> params = new ArrayList<Class<?>>();
+ while (pos.getIndex() < internal.length())
+ {
+ final char c = internal.charAt(pos.getIndex());
+ if (Character.isWhitespace(c)) {
+ pos.next();
+ continue;
+ }
+ final Character k = Character.valueOf(c);
+ if (REVERSE_ABBREVIATIONS.containsKey(k))
+ {
+ params.add(REVERSE_ABBREVIATIONS.get(k));
+ pos.next();
+ continue;
+ }
+ if (')' == c)
+ {
+ complete = true;
+ pos.next();
+ break;
+ }
+ try {
+ params.add(parseType(internal, pos));
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException(String.format("Method signature \"%s\" references unknown type",
+ internal), e);
+ }
+ }
+ Validate.isTrue(complete, "Method signature \"%s\" is incomplete", internal);
+ Validate.isTrue(StringUtils.isBlank(internal.substring(pos.getIndex())),
+ "Method signature \"%s\" includes unrecognized content beyond end", internal);
+
+ return Pair.of(name, params.toArray(ArrayUtils.EMPTY_CLASS_ARRAY));
+ }
+
+ private static Class<?> parseType(String internal, SignaturePosition pos) throws ClassNotFoundException {
+ final int here = pos.getIndex();
+ final char c = internal.charAt(here);
+
+ switch (c)
+ {
+ case '[':
+ pos.next();
+ final Class<?> componentType = parseType(internal, pos);
+ return Array.newInstance(componentType, 0).getClass();
+ case 'L':
+ pos.next();
+ final int type = pos.getIndex();
+ final int semi = internal.indexOf(';', type);
+ Validate.isTrue(semi > 0, "Type at index %s of method signature \"%s\" not terminated by semicolon", here,
+ internal);
+ final String className = internal.substring(type, semi).replace('/', '.');
+ Validate.notBlank(className, "Invalid classname at position %s of method signature \"%s\"", type, internal);
+ pos.setIndex(semi + 1);
+ return Class.forName(className);
+ default:
+ throw new IllegalArgumentException(String.format(
+ "Unexpected character at index %s of method signature \"%s\"", here, internal));
+ }
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Stored as a Java method descriptor minus return type.
+ */
+ private final String internal;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Create a new MethodSignature instance.
+ *
+ * @param method
+ */
+ public MethodSignature(Method method)
+ {
+ final StringBuilder buf = new StringBuilder(method.getName()).append('(');
+ for (Class<?> p : method.getParameterTypes())
+ {
+ appendTo(buf, p);
+ }
+ buf.append(')');
+ this.internal = buf.toString();
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Get the corresponding {@link Method} instance
+ * from the specified {@link Class}.
+ * @param type
+ * @return Method
+ */
+ public Method toMethod(Class<?> type)
+ {
+ final Pair<String,Class<?>[]> info = parse(internal);
+ return MethodUtils.getAccessibleMethod(type, info.getLeft(), info.getRight());
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Canonical Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object o)
+ {
+ if (o == null)
+ {
+ return false;
+ }
+ if (o == this)
+ {
+ return true;
+ }
+ if (o.getClass() != getClass())
+ {
+ return false;
+ }
+ MethodSignature other = (MethodSignature) o;
+ return other.internal.equals(internal);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(internal).build();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString()
+ {
+ return internal;
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java
similarity index 64%
rename from src/main/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java
rename to core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java
index ead88fc..726a046 100644
--- a/src/main/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassCache.java
@@ -1,116 +1,110 @@
-/*
- * 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.proxy.factory.util;
-
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * A cache for storing implementation classes for proxies based on a specific type of {@link ProxyClassGenerator}. A
- * proxy class cache ensures that there is only one class for every
- * {@link ProxyClassGenerator}/{@link ClassLoader}/proxy class array combination.
- *
- * @author James Carman
- * @since 1.0
- */
-public class ProxyClassCache
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Map loaderToClassCache = new WeakHashMap();
- private final ProxyClassGenerator proxyClassGenerator;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ProxyClassCache( ProxyClassGenerator proxyClassGenerator )
- {
- this.proxyClassGenerator = proxyClassGenerator;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Map getClassCache( ClassLoader classLoader )
- {
- Map cache = ( Map ) loaderToClassCache.get(classLoader);
- if( cache == null )
- {
- cache = new HashMap();
- loaderToClassCache.put(classLoader, cache);
- }
- return cache;
- }
-
- private String toClassCacheKey( Class[] proxyClasses )
- {
- final StringBuffer sb = new StringBuffer();
- for( int i = 0; i < proxyClasses.length; i++ )
- {
- Class proxyInterface = proxyClasses[i];
- sb.append(proxyInterface.getName());
- if( i != proxyClasses.length - 1 )
- {
- sb.append(",");
- }
- }
- return sb.toString();
- }
-
- /**
- * Returns the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
- * array of proxy classes.
- *
- * @param classLoader the classloader
- * @param proxyClasses the proxy classes
- * @return the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
- * array of proxy classes
- */
- public synchronized Class getProxyClass( ClassLoader classLoader, Class[] proxyClasses )
- {
- final Map classCache = getClassCache(classLoader);
- final String key = toClassCacheKey(proxyClasses);
- Class proxyClass;
- WeakReference proxyClassReference = ( WeakReference ) classCache.get(key);
- if( proxyClassReference == null )
- {
- proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
- classCache.put(key, new WeakReference(proxyClass));
- }
- else
- {
- synchronized( proxyClassReference )
- {
- proxyClass = ( Class ) proxyClassReference.get();
- if( proxyClass == null )
- {
- proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
- classCache.put(key, new WeakReference(proxyClass));
- }
- }
- }
- return proxyClass;
- }
-}
-
+/*
+ * 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.impl;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.*;
+
+/**
+ * A cache for storing implementation classes for proxies based on a specific type of {@link ProxyClassGenerator}. A
+ * proxy class cache ensures that there is only one class for every
+ * {@link ProxyClassGenerator}/{@link ClassLoader}/proxy class array combination.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class ProxyClassCache
+{
+
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final Map<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>> loaderToClassCache
+ = new WeakHashMap<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>>();
+ private final ProxyClassGenerator proxyClassGenerator;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new ProxyClassCache instance.
+ * @param proxyClassGenerator
+ */
+ public ProxyClassCache( ProxyClassGenerator proxyClassGenerator )
+ {
+ this.proxyClassGenerator = proxyClassGenerator;
+ }
+
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ private Map<Set<Class<?>>, WeakReference<Class<?>>> getClassCache( ClassLoader classLoader )
+ {
+ Map<Set<Class<?>>, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);
+ if( cache == null )
+ {
+ cache = new HashMap<Set<Class<?>>, WeakReference<Class<?>>>();
+ loaderToClassCache.put(classLoader, cache);
+ }
+ return cache;
+ }
+
+ private Set<Class<?>> toClassCacheKey( Class<?>[] proxyClasses )
+ {
+ return new HashSet<Class<?>>(Arrays.asList(proxyClasses));
+ }
+
+ /**
+ * Returns the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
+ * array of proxy classes.
+ *
+ * @param classLoader the classloader
+ * @param proxyClasses the proxy classes
+ * @return the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
+ * array of proxy classes
+ */
+ public synchronized Class<?> getProxyClass( ClassLoader classLoader, Class<?>[] proxyClasses )
+ {
+ final Map<Set<Class<?>>, WeakReference<Class<?>>> classCache = getClassCache(classLoader);
+ final Set<Class<?>> key = toClassCacheKey(proxyClasses);
+ Class<?> proxyClass;
+ Reference<Class<?>> proxyClassReference = classCache.get(key);
+ if( proxyClassReference == null )
+ {
+ proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
+ classCache.put(key, new WeakReference<Class<?>>(proxyClass));
+ }
+ else
+ {
+ synchronized( proxyClassReference )
+ {
+ proxyClass = proxyClassReference.get();
+ if( proxyClass == null )
+ {
+ proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
+ classCache.put(key, new WeakReference<Class<?>>(proxyClass));
+ }
+ }
+ }
+ return proxyClass;
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java
similarity index 72%
rename from src/main/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java
rename to core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java
index effd113..531ca3f 100644
--- a/src/main/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java
+++ b/core/src/main/java/org/apache/commons/proxy2/impl/ProxyClassGenerator.java
@@ -1,41 +1,43 @@
-/*
- * 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.proxy.factory.util;
-
-/**
- * A proxy class generator generates specific type of proxies (interceptor, invoker, etc.).
- *
- * @author James Carman
- * @since 1.0
- */
-public interface ProxyClassGenerator
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * Generates a proxy class for the supplied {@link ClassLoader} and proxy classes.
- *
- * @param classLoader the classloader
- * @param proxyClasses the proxy classes
- * @return the dynamically generated proxy class
- */
- public Class generateProxyClass( ClassLoader classLoader, Class[] proxyClasses );
-}
-
+/*
+ * 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.impl;
+
+/**
+ * A proxy class generator generates Class instances for a given combination of interfaces
+ * in a given classloader. Typically, in the context of a {@link org.apache.commons.proxy2.ProxyFactory}
+ * implementation, an instance will generate proxy class instances for a specific type of proxies (interceptor,
+ * invoker, etc.) and will be associated with a corresponding {@link ProxyClassCache}.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public interface ProxyClassGenerator
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ /**
+ * Generates a proxy class for the supplied {@link ClassLoader} and proxy classes.
+ *
+ * @param classLoader the classloader
+ * @param proxyClasses the proxy classes
+ * @return the dynamically generated proxy class
+ */
+ Class<?> generateProxyClass( ClassLoader classLoader, Class<?>... proxyClasses );
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/InterceptorUtils.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/InterceptorUtils.java
new file mode 100644
index 0000000..7751bc1
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/InterceptorUtils.java
@@ -0,0 +1,92 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.provider.ObjectProviderUtils;
+
+public final class InterceptorUtils
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Static Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Creates an {@link Interceptor} which always returns a constant value (for all methods).
+ * @param value the constant
+ * @return an {@link Interceptor} which always returns a constant value (for all methods)
+ */
+ public static Interceptor constant(Object value)
+ {
+ return new ObjectProviderInterceptor(ObjectProviderUtils.constant(value));
+ }
+
+ /**
+ * Creates an {@link Interceptor} which returns the resulting object from an
+ * object provider (for all methods).
+ * @param provider the object provider
+ * @return an {@link Interceptor} which returns the resulting object from an
+ * object provider (for all methods)
+ */
+ public static Interceptor provider(ObjectProvider<?> provider)
+ {
+ return new ObjectProviderInterceptor(provider);
+ }
+
+ /**
+ * Creates an {@link Interceptor} which throws a specific exception (for all methods).
+ * @param e the exception
+ * @return an {@link Interceptor} which throws a specific exception (for all methods)
+ */
+ public static Interceptor throwing(Exception e)
+ {
+ return new ThrowingInterceptor(ObjectProviderUtils.constant(e));
+ }
+
+ /**
+ * Creates an {@link Interceptor} which throws the exception provided by an object
+ * provider (for all methods).
+ * @param provider the object provider
+ * @return an {@link Interceptor} which throws the exception provided by an object
+ * provider (for all methods)
+ */
+ public static Interceptor throwing(ObjectProvider<? extends Exception> provider)
+ {
+ return new ThrowingInterceptor(provider);
+ }
+
+ /**
+ * Creates an {@link Interceptor} that delegates to the specified {@link Invoker}.
+ * @param invoker delegate
+ * @return invoker {@link Interceptor}
+ */
+ public static Interceptor invoking(Invoker invoker)
+ {
+ return new InvokerInterceptor(invoker);
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ private InterceptorUtils()
+ {
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/InvokerInterceptor.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/InvokerInterceptor.java
new file mode 100644
index 0000000..d4fdaea
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/InvokerInterceptor.java
@@ -0,0 +1,46 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.Invoker;
+
+/**
+ * Adapts an {@link Invoker} to the {@link Interceptor} interface.
+ */
+public class InvokerInterceptor implements Interceptor
+{
+ private static final long serialVersionUID = 1L;
+
+ private final Invoker invoker;
+
+ public InvokerInterceptor(Invoker invoker)
+ {
+ super();
+ this.invoker = Validate.notNull(invoker);
+ }
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable
+ {
+ return invoker.invoke(invocation.getProxy(), invocation.getMethod(), invocation.getArguments());
+ }
+
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/ObjectProviderInterceptor.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/ObjectProviderInterceptor.java
new file mode 100644
index 0000000..250aae4
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/ObjectProviderInterceptor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * A {@link ObjectProviderInterceptor} merely returns the value returned from
+ * {@link org.apache.commons.proxy2.ObjectProvider#getObject()}.
+ */
+public class ObjectProviderInterceptor implements Interceptor
+{
+ private static final long serialVersionUID = 1L;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final ObjectProvider<?> provider;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public ObjectProviderInterceptor(ObjectProvider<?> provider)
+ {
+ this.provider = Validate.notNull(provider, "Provider cannot be null.");
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Interceptor Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable
+ {
+ return provider.getObject();
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/SwitchInterceptor.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/SwitchInterceptor.java
new file mode 100644
index 0000000..a06b1d2
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/SwitchInterceptor.java
@@ -0,0 +1,99 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.InvocationMatcher;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A {@link SwitchInterceptor} maintains a list of {@link org.apache.commons.proxy2.interceptor.matcher.InvocationMatcher}/{@link Interceptor} pairs. Each
+ * invocation will be checked against the registered InvocationMatchers. If one matches the current invocation, then
+ * the corresponding Interceptor will be called. If no InvocationMatchers match, then the invocation will merely
+ * {@link org.apache.commons.proxy2.Invocation#proceed()} method is called.
+ */
+public class SwitchInterceptor implements Interceptor, Serializable
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private static final long serialVersionUID = 1L;
+
+ private final List<Pair<InvocationMatcher, Interceptor>> cases = new CopyOnWriteArrayList<Pair<InvocationMatcher, Interceptor>>();
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public SwitchInterceptor()
+ {
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Interceptor Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable
+ {
+ for (Pair<InvocationMatcher, Interceptor> currentCase : cases)
+ {
+ if (currentCase.getLeft().matches(invocation))
+ {
+ return currentCase.getRight().intercept(invocation);
+ }
+ }
+ return invocation.proceed();
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public CaseBuilder when(InvocationMatcher matcher)
+ {
+ return new CaseBuilder(matcher);
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Inner Classes
+//----------------------------------------------------------------------------------------------------------------------
+
+ public class CaseBuilder
+ {
+ private final InvocationMatcher matcher;
+
+ public CaseBuilder(InvocationMatcher matcher)
+ {
+ this.matcher = matcher;
+ }
+
+ public SwitchInterceptor then(Interceptor interceptor)
+ {
+ cases.add(new ImmutablePair<InvocationMatcher, Interceptor>(matcher, interceptor));
+ return SwitchInterceptor.this;
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/ThrowingInterceptor.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/ThrowingInterceptor.java
new file mode 100644
index 0000000..9201e29
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/ThrowingInterceptor.java
@@ -0,0 +1,52 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.ObjectProvider;
+
+public class ThrowingInterceptor implements Interceptor
+{
+ private static final long serialVersionUID = 1L;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final ObjectProvider<? extends Exception> provider;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public ThrowingInterceptor(ObjectProvider<? extends Exception> provider)
+ {
+ this.provider = provider;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Interceptor Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable
+ {
+ throw provider.getObject();
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/ArgumentMatcher.java
similarity index 66%
copy from src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
copy to core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/ArgumentMatcher.java
index f73551d..db3c586 100644
--- a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/ArgumentMatcher.java
@@ -15,17 +15,13 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.util;
+package org.apache.commons.proxy2.interceptor.matcher;
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface DuplicateEcho
+public interface ArgumentMatcher<T>
{
-//**********************************************************************************************************************
+//----------------------------------------------------------------------------------------------------------------------
// Other Methods
-//**********************************************************************************************************************
+//----------------------------------------------------------------------------------------------------------------------
- public String echoBack( String message );
+ boolean matches(T argument);
}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/InvocationMatcher.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/InvocationMatcher.java
new file mode 100644
index 0000000..a439b01
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/InvocationMatcher.java
@@ -0,0 +1,33 @@
+/*
+ * 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.interceptor.matcher;
+
+import org.apache.commons.proxy2.Invocation;
+
+/**
+ * An {@link InvocationMatcher} is used to conditionally match {@link Invocation} objects based on
+ * some criteria such as method name, parameter values, etc.
+ */
+public interface InvocationMatcher
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ boolean matches(Invocation invocation);
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/argument/ArgumentMatcherUtils.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/argument/ArgumentMatcherUtils.java
new file mode 100644
index 0000000..bc7e295
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/argument/ArgumentMatcherUtils.java
@@ -0,0 +1,291 @@
+/*
+ * 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.interceptor.matcher.argument;
+
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.proxy2.interceptor.matcher.ArgumentMatcher;
+
+public final class ArgumentMatcherUtils
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Static Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public static <T> ArgumentMatcher<T> any()
+ {
+ return new AnyMatcher<T>();
+ }
+
+ public static ArgumentMatcher<String> endsWith(String suffix)
+ {
+ return new EndsWithMatcher(Validate.notNull(suffix));
+ }
+
+ public static <T> ArgumentMatcher<T> eq(final T value)
+ {
+ return new EqualsMatcher<T>(value);
+ }
+
+ public static <C extends Comparable<?>> ArgumentMatcher<C> gt(C comparable)
+ {
+ return new GreaterThanMatcher<C>(comparable);
+ }
+
+ public static <C extends Comparable<?>> ArgumentMatcher<C> gte(C comparable)
+ {
+ return new GreaterThanOrEqualMatcher<C>(comparable);
+ }
+
+ public static <T> ArgumentMatcher<T> isA(final Class<?> type)
+ {
+ return new InstanceOfMatcher<T>(type);
+ }
+
+ public static <T> ArgumentMatcher<T> isNull()
+ {
+ return new IsNullMatcher<T>();
+ }
+
+ public static <C extends Comparable<?>> ArgumentMatcher<C> lt(C comparable)
+ {
+ return new LessThanMatcher<C>(comparable);
+ }
+
+ public static <C extends Comparable<?>> ArgumentMatcher<C> lte(C comparable)
+ {
+ return new LessThanOrEqualMatcher<C>(comparable);
+ }
+
+ public static ArgumentMatcher<String> matches(String regex)
+ {
+ return new RegexMatcher(Validate.notNull(regex));
+ }
+
+ public static <T> ArgumentMatcher<T> notNull()
+ {
+ return new NotNullMatcher<T>();
+ }
+
+ public static ArgumentMatcher<String> startsWith(String prefix)
+ {
+ return new StartsWithMatcher(Validate.notNull(prefix));
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ private ArgumentMatcherUtils()
+ {
+
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Inner Classes
+//----------------------------------------------------------------------------------------------------------------------
+
+ private static final class AnyMatcher<T> implements ArgumentMatcher<T>
+ {
+ @Override
+ public boolean matches(T argument)
+ {
+ return true;
+ }
+ }
+
+ private abstract static class ComparatorMatcher<C extends Comparable<?>> implements ArgumentMatcher<C>
+ {
+ private final C comparable;
+
+ protected ComparatorMatcher(C comparable)
+ {
+ this.comparable = Validate.notNull(comparable);
+ }
+
+ protected abstract boolean evaluate(int comparison);
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean matches(C argument)
+ {
+ if (argument == null)
+ {
+ return false;
+ }
+ @SuppressWarnings("rawtypes")
+ final int comparison = ((Comparable) comparable).compareTo(argument);
+ return evaluate(comparison);
+ }
+ }
+
+ public static class EndsWithMatcher implements ArgumentMatcher<String>
+ {
+ private final String suffix;
+
+ public EndsWithMatcher(String suffix)
+ {
+ this.suffix = suffix;
+ }
+
+ @Override
+ public boolean matches(String argument)
+ {
+ return StringUtils.endsWith(argument, suffix);
+ }
+ }
+
+ private static final class EqualsMatcher<T> implements ArgumentMatcher<T>
+ {
+ private final T value;
+
+ public EqualsMatcher(T value)
+ {
+ this.value = value;
+ }
+
+ @Override
+ public boolean matches(T argument)
+ {
+ return ObjectUtils.equals(argument, value);
+ }
+ }
+
+ private static final class GreaterThanMatcher<C extends Comparable<?>> extends ComparatorMatcher<C>
+ {
+ private GreaterThanMatcher(C comparable)
+ {
+ super(comparable);
+ }
+
+ @Override
+ protected boolean evaluate(int comparison)
+ {
+ return comparison < 0;
+ }
+ }
+
+ private static final class GreaterThanOrEqualMatcher<C extends Comparable<?>> extends ComparatorMatcher<C>
+ {
+ private GreaterThanOrEqualMatcher(C comparable)
+ {
+ super(comparable);
+ }
+
+ @Override
+ protected boolean evaluate(int comparison)
+ {
+ return comparison <= 0;
+ }
+ }
+
+ private static final class InstanceOfMatcher<T> implements ArgumentMatcher<T>
+ {
+ private final Class<?> type;
+
+ public InstanceOfMatcher(Class<?> type)
+ {
+ this.type = Validate.notNull(type, "type");
+ }
+
+ @Override
+ public boolean matches(T argument)
+ {
+ return type.isInstance(argument);
+ }
+ }
+
+ private static final class IsNullMatcher<T> implements ArgumentMatcher<T>
+ {
+ @Override
+ public boolean matches(T argument)
+ {
+ return argument == null;
+ }
+ }
+
+ private static final class LessThanMatcher<C extends Comparable<?>> extends ComparatorMatcher<C>
+ {
+ private LessThanMatcher(C comparable)
+ {
+ super(comparable);
+ }
+
+ @Override
+ protected boolean evaluate(int comparison)
+ {
+ return comparison > 0;
+ }
+ }
+
+ private static final class LessThanOrEqualMatcher<C extends Comparable<?>> extends ComparatorMatcher<C>
+ {
+ private LessThanOrEqualMatcher(C comparable)
+ {
+ super(comparable);
+ }
+
+ @Override
+ protected boolean evaluate(int comparison)
+ {
+ return comparison >= 0;
+ }
+ }
+
+ private static final class NotNullMatcher<T> implements ArgumentMatcher<T>
+ {
+ @Override
+ public boolean matches(T argument)
+ {
+ return argument != null;
+ }
+ }
+
+ public static class RegexMatcher implements ArgumentMatcher<String>
+ {
+ private final String regex;
+
+ public RegexMatcher(String regex)
+ {
+ this.regex = regex;
+ }
+
+ @Override
+ public boolean matches(String argument)
+ {
+ return argument != null && argument.matches(regex);
+ }
+ }
+
+ private static final class StartsWithMatcher implements ArgumentMatcher<String>
+ {
+ private final String prefix;
+
+ private StartsWithMatcher(String prefix)
+ {
+ this.prefix = prefix;
+ }
+
+ @Override
+ public boolean matches(String argument)
+ {
+ return StringUtils.startsWith(argument, prefix);
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/DeclaredByMatcher.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/DeclaredByMatcher.java
new file mode 100644
index 0000000..c881b0b
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/DeclaredByMatcher.java
@@ -0,0 +1,75 @@
+/*
+ * 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.interceptor.matcher.invocation;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.InvocationMatcher;
+
+/**
+ * InvocationMatcher based on declaring class of the method invoked.
+ */
+public class DeclaredByMatcher implements InvocationMatcher
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final boolean exactMatch;
+ private final Class<?> declaredByType;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Equivalent to {@link #DeclaredByMatcher(Class, boolean)}{@code (declaredByType, false)}
+ * @param declaredByType
+ */
+ public DeclaredByMatcher(Class<?> declaredByType)
+ {
+ this(declaredByType, false);
+ }
+
+ /**
+ * Create a {@link DeclaredByMatcher} instance.
+ *
+ * @param declaredByType
+ * type by which method must be declared
+ * @param exactMatch
+ * if {@code false}, {@code declaredByType} may be a subclass of
+ * the actual declaring class of the invocation method.
+ */
+ public DeclaredByMatcher(Class<?> declaredByType, boolean exactMatch)
+ {
+ this.declaredByType = declaredByType;
+ this.exactMatch = exactMatch;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// InvocationMatcher Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Override
+ public boolean matches(Invocation invocation)
+ {
+ final Class<?> owner = invocation.getMethod().getDeclaringClass();
+ return exactMatch ?
+ declaredByType.equals(owner) :
+ owner.isAssignableFrom(declaredByType);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/MethodNameMatcher.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/MethodNameMatcher.java
new file mode 100644
index 0000000..7eaa7ef
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/MethodNameMatcher.java
@@ -0,0 +1,53 @@
+/*
+ * 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.interceptor.matcher.invocation;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.InvocationMatcher;
+
+/**
+ * A {@link MethodNameMatcher} simply checks to see that the method name of the invocation matches the target method
+ * name given in the constructor.
+ */
+public class MethodNameMatcher implements InvocationMatcher
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final String methodName;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public MethodNameMatcher(String methodName)
+ {
+ this.methodName = methodName;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// InvocationMatcher Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Override
+ public boolean matches(Invocation invocation)
+ {
+ return methodName.equals(invocation.getMethod().getName());
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/ReturnTypeMatcher.java b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/ReturnTypeMatcher.java
new file mode 100644
index 0000000..9b7d743
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/interceptor/matcher/invocation/ReturnTypeMatcher.java
@@ -0,0 +1,59 @@
+/*
+ * 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.interceptor.matcher.invocation;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.InvocationMatcher;
+
+public class ReturnTypeMatcher implements InvocationMatcher
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final boolean exactMatch;
+ private final Class<?> returnType;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public ReturnTypeMatcher(Class<?> returnType)
+ {
+ this(returnType, false);
+ }
+
+ public ReturnTypeMatcher(Class<?> returnType, boolean exactMatch)
+ {
+ this.returnType = returnType;
+ this.exactMatch = exactMatch;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// InvocationMatcher Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+
+ @Override
+ public boolean matches(Invocation invocation)
+ {
+ return exactMatch ?
+ returnType.equals(invocation.getMethod().getReturnType()) :
+ returnType.isAssignableFrom(invocation.getMethod().getReturnType());
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/DelegatingInvoker.java b/core/src/main/java/org/apache/commons/proxy2/invoker/DelegatingInvoker.java
new file mode 100644
index 0000000..4607847
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/DelegatingInvoker.java
@@ -0,0 +1,58 @@
+/*
+ * 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.invoker;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * Delegates a method invocation to the object provided by an
+ * {@link ObjectProvider}.
+ *
+ * @param <T>
+ */
+public class DelegatingInvoker<T> implements Invoker
+{
+ private static final long serialVersionUID = 1L;
+
+ private final ObjectProvider<? extends T> delegateProvider;
+
+ public DelegatingInvoker(ObjectProvider<? extends T> delegateProvider)
+ {
+ super();
+ this.delegateProvider = Validate.notNull(delegateProvider);
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable
+ {
+ try
+ {
+ return method.invoke(delegateProvider.getObject(), arguments);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw e.getTargetException();
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java b/core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java
similarity index 72%
rename from src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java
rename to core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java
index 1992594..0e6a11d 100644
--- a/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/DuckTypingInvoker.java
@@ -1,94 +1,104 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.ObjectProvider;
-
-import java.lang.reflect.Method;
-
-/**
- * An invoker which supports <a href="http://en.wikipedia.org/wiki/Duck_typing">"duck typing"</a>, meaning
- * that it finds a matching method on the object returned from the target provider and invokes it. This class is
- * useful for adapting an existing class to an interface it does not implement.
- * <p>
- * <b>Example:</b>
- * </p>
- * <p>
- * <pre>
- * public class LegacyDuck // Does not implement interface!
- * {
- * public void quack()
- * {
- * // Quacking logic...
- * }
- * }
- * <p/>
- * public interface Duck
- * {
- * public void quack();
- * }
- * <p/>
- * ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck()); // Always returns a "legacy" duck
- * DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- * Duck duck = ( Duck )proxyFactory.createInvokerProxy( invoker, new Class[] { Duck.class } );
- * </pre>
- * </p>
- */
-public class DuckTypingInvoker implements Invoker
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final ObjectProvider targetProvider;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public DuckTypingInvoker( final ObjectProvider targetProvider )
- {
- this.targetProvider = targetProvider;
- }
-
-//**********************************************************************************************************************
-// Invoker Implementation
-//**********************************************************************************************************************
-
- public Object invoke( final Object proxy, final Method method, final Object[] arguments ) throws Throwable
- {
- final Object target = targetProvider.getObject();
- final Class targetClass = target.getClass();
- try
- {
- final Method targetMethod = targetClass.getMethod(method.getName(), method.getParameterTypes());
- if( method.getReturnType().isAssignableFrom(targetMethod.getReturnType()) )
- {
- return targetMethod.invoke(target, arguments);
- }
- throw new UnsupportedOperationException(
- "Target type " + targetClass.getName() + " method has incompatible return type.");
- }
- catch( NoSuchMethodException e )
- {
- throw new UnsupportedOperationException(
- "Target type " + targetClass.getName() + " does not have a method matching " + method + ".");
- }
- }
-}
+/*
+ * 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.invoker;
+
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+
+import java.lang.reflect.Method;
+
+/**
+ * An invoker which supports <a href="http://en.wikipedia.org/wiki/Duck_typing">"duck typing"</a>, meaning
+ * that it finds a matching method on the object returned from the target provider and invokes it. This class is
+ * useful for adapting an existing class to an interface it does not implement.
+ * <p>
+ * <b>Example:</b>
+ * </p>
+ * <p>
+ * <pre>
+ * public class LegacyDuck // Does not implement interface!
+ * {
+ * public void quack()
+ * {
+ * // Quacking logic...
+ * }
+ * }
+ * <p/>
+ * public interface Duck
+ * {
+ * public void quack();
+ * }
+ * <p/>
+ * ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck()); // Always returns a "legacy" duck
+ * DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
+ * Duck duck = ( Duck )proxyFactory.createInvokerProxy( invoker, new Class[] { Duck.class } );
+ * </pre>
+ * </p>
+ */
+public class DuckTypingInvoker implements Invoker
+{
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final ObjectProvider<?> targetProvider;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new DuckTypingInvoker instance.
+ * @param targetProvider
+ */
+ public DuckTypingInvoker( final ObjectProvider<?> targetProvider )
+ {
+ this.targetProvider = targetProvider;
+ }
+
+ //**********************************************************************************************************************
+ // Invoker Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke( final Object proxy, final Method method, final Object[] arguments ) throws Throwable
+ {
+ final Object target = targetProvider.getObject();
+ final Class<?> targetClass = target.getClass();
+ try
+ {
+ final Method targetMethod = targetClass.getMethod(method.getName(), method.getParameterTypes());
+ if( method.getReturnType().isAssignableFrom(targetMethod.getReturnType()) )
+ {
+ return targetMethod.invoke(target, arguments);
+ }
+ throw new UnsupportedOperationException(
+ "Target type " + targetClass.getName() + " method has incompatible return type.");
+ }
+ catch( NoSuchMethodException e )
+ {
+ throw new UnsupportedOperationException(
+ "Target type " + targetClass.getName() + " does not have a method matching " + method + ".", e);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/invoker/InvocationHandlerAdapter.java b/core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java
similarity index 67%
rename from src/main/java/org/apache/commons/proxy/invoker/InvocationHandlerAdapter.java
rename to core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java
index f59efb3..71714ba 100644
--- a/src/main/java/org/apache/commons/proxy/invoker/InvocationHandlerAdapter.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/InvocationHandlerAdapter.java
@@ -1,58 +1,67 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.Invoker;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
-/**
- * An adapter class to adapt the JDK's {@link InvocationHandler} interface to Commons Proxy's
- * {@link Invoker} interface.
- *
- * @author James Carman
- * @since 1.0
- */
-public class InvocationHandlerAdapter implements Invoker
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final InvocationHandler invocationHandler;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public InvocationHandlerAdapter( InvocationHandler invocationHandler )
- {
- this.invocationHandler = invocationHandler;
- }
-
-//**********************************************************************************************************************
-// Invoker Implementation
-//**********************************************************************************************************************
-
-
- public Object invoke( Object proxy, Method method, Object[] arguments ) throws Throwable
- {
- return invocationHandler.invoke(proxy, method, arguments);
- }
-}
+/*
+ * 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.invoker;
+
+import org.apache.commons.proxy2.Invoker;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * An adapter class to adapt the JDK's {@link InvocationHandler} interface to Commons Proxy's
+ * {@link Invoker} interface.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class InvocationHandlerAdapter implements Invoker
+{
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final InvocationHandler invocationHandler;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new InvocationHandlerAdapter instance.
+ * @param invocationHandler
+ */
+ public InvocationHandlerAdapter( InvocationHandler invocationHandler )
+ {
+ this.invocationHandler = invocationHandler;
+ }
+
+ //**********************************************************************************************************************
+ // Invoker Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke( Object proxy, Method method, Object[] arguments ) throws Throwable
+ {
+ return invocationHandler.invoke(proxy, method, arguments);
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java b/core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java
similarity index 62%
rename from src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java
rename to core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java
index 093cb1e..1bcc33e 100644
--- a/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/NullInvoker.java
@@ -1,46 +1,55 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.ProxyUtils;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-/**
- * An {@link Invoker} implementation which merely returns null for all method invocations. This class is
- * useful for scenarios where the "null object" design pattern is needed.
- *
- * @author James Carman
- * @since 1.0
- */
-public class NullInvoker implements Invoker, Serializable
-{
-//**********************************************************************************************************************
-// Invoker Implementation
-//**********************************************************************************************************************
-
- public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
- {
- final Class returnType = method.getReturnType();
- return ProxyUtils.getDefaultValue(returnType);
- }
-
-}
-
+/*
+ * 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.invoker;
+
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ProxyUtils;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+/**
+ * An {@link Invoker} implementation which merely returns null for all method invocations. This class is
+ * useful for scenarios where the "null object" design pattern is needed.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class NullInvoker implements Invoker, Serializable
+{
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Statically available instance.
+ */
+ public static final NullInvoker INSTANCE = new NullInvoker();
+
+ //**********************************************************************************************************************
+ // Invoker Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
+ {
+ final Class<?> returnType = method.getReturnType();
+ return ProxyUtils.nullValue(returnType);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java b/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java
new file mode 100644
index 0000000..ada8299
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/RecordedInvocation.java
@@ -0,0 +1,152 @@
+/*
+ * 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.invoker;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.proxy2.ProxyUtils;
+
+import java.lang.reflect.Method;
+
+/**
+ * Detached representation of a method invocation.
+ *
+ * @author James Carman
+ */
+public class RecordedInvocation
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final Method invokedMethod;
+ private final Object[] arguments;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Create a new RecordedInvocation instance.
+ *
+ * @param invokedMethod
+ * @param arguments
+ */
+ public RecordedInvocation(Method invokedMethod, Object[] arguments)
+ {
+ this.invokedMethod = invokedMethod;
+ this.arguments = ArrayUtils.nullToEmpty(ArrayUtils.clone(arguments));
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Getter/Setter Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Get the invokedMethod.
+ *
+ * @return Method
+ */
+ public Method getInvokedMethod()
+ {
+ return invokedMethod;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Canonical Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(invokedMethod.getDeclaringClass().getName());
+ buffer.append(".");
+ buffer.append(invokedMethod.getName());
+ buffer.append("(");
+ int count = arguments.length;
+ for (int i = 0; i < count; i++)
+ {
+ Object arg = arguments[i];
+ if (i > 0)
+ {
+ buffer.append(", ");
+ }
+ convert(buffer, arg);
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Add a string representation of <code>input</code> to <code>buffer</code>.
+ *
+ * @param buffer
+ * @param input
+ */
+ protected void convert(StringBuilder buffer, Object input)
+ {
+ if (input == null)
+ {
+ buffer.append("<null>");
+ return;
+ }
+
+ // Primitive types, and non-object arrays
+ // use toString().
+ if (!(input instanceof Object[]))
+ {
+ buffer.append(input.toString());
+ return;
+ }
+ else
+ {
+ buffer.append("(");
+ buffer.append(ProxyUtils.getJavaClassName(input.getClass()));
+ buffer.append("){");
+ Object[] array = (Object[]) input;
+ int count = array.length;
+ for (int i = 0; i < count; i++)
+ {
+ if (i > 0)
+ {
+ buffer.append(", ");
+ }
+ // We use convert() again, because it could be a multi-dimensional array
+ // where each element must be converted.
+ convert(buffer, array[i]);
+ }
+ buffer.append("}");
+ }
+ }
+
+ /**
+ * Get the arguments.
+ *
+ * @return Object[]
+ */
+ public Object[] getArguments()
+ {
+ return ArrayUtils.clone(arguments);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java b/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java
new file mode 100644
index 0000000..20149d2
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/invoker/recorder/InvocationRecorder.java
@@ -0,0 +1,119 @@
+/*
+ * 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.invoker.recorder;
+
+import org.apache.commons.lang3.reflect.TypeUtils;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.invoker.RecordedInvocation;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * An {@link InvocationRecorder} records method invocations against its generated proxies.
+ * @author James Carman
+ */
+public class InvocationRecorder
+{
+ private final ProxyFactory proxyFactory;
+ private List<RecordedInvocation> recordedInvocations = new LinkedList<RecordedInvocation>();
+
+ /**
+ * Create a new InvocationRecorder instance.
+ * @param proxyFactory
+ */
+ public InvocationRecorder( ProxyFactory proxyFactory )
+ {
+ this.proxyFactory = proxyFactory;
+ }
+
+ /**
+ * Get the invocations that have been recorded up to this point. The list is "live" and should not be modified.
+ * @return {@link List} of {@link RecordedInvocation}
+ */
+ public List<RecordedInvocation> getRecordedInvocations()
+ {
+ return recordedInvocations;
+ }
+
+ /**
+ * Generate a recording proxy for the specified class.
+ * @param <T>
+ * @param type
+ * @return the generated proxy
+ */
+ public <T> T proxy( Class<T> type )
+ {
+ return proxy(type, type);
+ }
+
+ /**
+ * Generate a recording proxy for the specified class, qualified as <code>genericType</code>.
+ * @param <T>
+ * @param genericType
+ * @param type
+ * @return the generated proxy
+ */
+ public <T> T proxy( Type genericType, Class<T> type )
+ {
+ if( proxyFactory.canProxy(type) )
+ {
+ @SuppressWarnings("unchecked")
+ final T result = (T) proxyFactory.createInvokerProxy(new InvocationRecorderInvoker(genericType), type);
+ return result;
+ }
+ return ProxyUtils.nullValue(type);
+ }
+
+ private final class InvocationRecorderInvoker implements Invoker
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Type targetType;
+
+ private InvocationRecorderInvoker( Type targetType )
+ {
+ this.targetType = targetType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke( Object o, Method method, Object[] args ) throws Throwable
+ {
+ recordedInvocations.add(new RecordedInvocation(method, args));
+ final Class<?> returnType = TypeUtils.getRawType(method.getGenericReturnType(), targetType);
+ //what to do if returnType is null?
+ return proxy(method.getGenericReturnType(), returnType);
+ }
+ }
+
+ /**
+ * Reset this {@link InvocationRecorder}.
+ */
+ public void reset()
+ {
+ recordedInvocations.clear();
+ }
+
+}
diff --git a/src/main/java/org/apache/commons/proxy/provider/BeanProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java
similarity index 73%
rename from src/main/java/org/apache/commons/proxy/provider/BeanProvider.java
rename to core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java
index f63003a..68b0d4c 100644
--- a/src/main/java/org/apache/commons/proxy/provider/BeanProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/BeanProvider.java
@@ -1,91 +1,81 @@
-/*
- * 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.proxy.provider;
-
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import java.io.Serializable;
-
-/**
- * Uses <code>Class.newInstance()</code> to instantiate an object.
- *
- * @author James Carman
- * @since 1.0
- */
-public class BeanProvider implements ObjectProvider, Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private Class beanClass;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public BeanProvider()
- {
- }
-
- /**
- * Constructs a provider which instantiates objects of the specified bean class.
- *
- * @param beanClass the bean class
- */
- public BeanProvider( Class beanClass )
- {
- this.beanClass = beanClass;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- try
- {
- if( beanClass == null )
- {
- throw new ObjectProviderException("No bean class provided.");
- }
- return beanClass.newInstance();
- }
- catch( InstantiationException e )
- {
- throw new ObjectProviderException("Class " + beanClass.getName() + " is not concrete.", e);
- }
- catch( IllegalAccessException e )
- {
- throw new ObjectProviderException("Constructor for class " + beanClass.getName() + " is not accessible.",
- e);
- }
- }
-
-//**********************************************************************************************************************
-// Getter/Setter Methods
-//**********************************************************************************************************************
-
- public void setBeanClass( Class beanClass )
- {
- this.beanClass = beanClass;
- }
-}
-
+/*
+ * 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.provider;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+
+import java.io.Serializable;
+
+/**
+ * Uses <code>Class.newInstance()</code> to instantiate an object.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class BeanProvider<T> implements ObjectProvider<T>, Serializable
+{
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final Class<? extends T> beanClass;
+
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ /**
+ * Constructs a provider which instantiates objects of the specified bean class.
+ *
+ * @param beanClass the bean class
+ */
+ public BeanProvider( Class<? extends T> beanClass )
+ {
+ Validate.notNull(beanClass, "Bean class cannot be null.");
+ this.beanClass = beanClass;
+ }
+
+//**********************************************************************************************************************
+// ObjectProvider Implementation
+//**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ public T getObject()
+ {
+ try
+ {
+ return beanClass.newInstance();
+ }
+ catch( InstantiationException e )
+ {
+ throw new ObjectProviderException("Class " + beanClass.getName() + " is not concrete.", e);
+ }
+ catch( IllegalAccessException e )
+ {
+ throw new ObjectProviderException("Constructor for class " + beanClass.getName() + " is not accessible.",
+ e);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/provider/CloningProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java
similarity index 60%
rename from src/main/java/org/apache/commons/proxy/provider/CloningProvider.java
rename to core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java
index b99fcee..2b494c4 100644
--- a/src/main/java/org/apache/commons/proxy/provider/CloningProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/CloningProvider.java
@@ -1,101 +1,103 @@
-/*
- * 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.proxy.provider;
-
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.ProxyUtils;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Merely calls <code>clone()</code> (reflectively) on the given {@link Cloneable} object.
- *
- * @author James Carman
- * @since 1.0
- */
-public class CloningProvider implements ObjectProvider, Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Cloneable cloneable;
- private Method cloneMethod;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- /**
- * Constructs a provider which returns clone copies of the specified {@link Cloneable}
- * object.
- *
- * @param cloneable the object to clone
- */
- public CloningProvider( Cloneable cloneable )
- {
- this.cloneable = cloneable;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
-
- public Object getObject()
- {
- try
- {
- return getCloneMethod().invoke(cloneable, ProxyUtils.EMPTY_ARGUMENTS);
- }
- catch( IllegalAccessException e )
- {
- throw new ObjectProviderException(
- "Class " + cloneable.getClass().getName() + " does not have a public clone() method.", e);
- }
- catch( InvocationTargetException e )
- {
- throw new ObjectProviderException(
- "Attempt to clone object of type " + cloneable.getClass().getName() + " threw an exception.", e);
- }
- }
-
-//**********************************************************************************************************************
-// Getter/Setter Methods
-//**********************************************************************************************************************
-
- private synchronized Method getCloneMethod()
- {
- if( cloneMethod == null )
- {
- try
- {
- cloneMethod = cloneable.getClass().getMethod("clone", ProxyUtils.EMPTY_ARGUMENT_TYPES);
- }
- catch( NoSuchMethodException e )
- {
- throw new ObjectProviderException(
- "Class " + cloneable.getClass().getName() + " does not have a public clone() method.");
- }
- }
- return cloneMethod;
- }
-}
+/*
+ * 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.provider;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Merely calls <code>clone()</code> (reflectively) on the given {@link Cloneable} object.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class CloningProvider<T extends Cloneable> implements ObjectProvider<T>, Serializable
+{
+ /**
+ * Serialization version
+ */
+ private static final long serialVersionUID = 1L;
+
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final T cloneable;
+
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ /**
+ * Constructs a provider which returns clone copies of the specified {@link Cloneable}
+ * object.
+ *
+ * @param cloneable the object to clone
+ */
+ public CloningProvider(T cloneable)
+ {
+ Validate.notNull(cloneable, "Cloneable object cannot be null.");
+ Validate.isTrue(
+ MethodUtils.getAccessibleMethod(cloneable.getClass(), "clone") != null,
+ String.format("Class %s does not override clone() method as public.",
+ cloneable.getClass().getName()));
+ this.cloneable = cloneable;
+ }
+
+ //**********************************************************************************************************************
+ // ObjectProvider Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public T getObject()
+ {
+ try
+ {
+ return (T) MethodUtils.invokeExactMethod(cloneable, "clone");
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new ObjectProviderException(
+ "Class " + cloneable.getClass().getName() + " does not have a public clone() method.", e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new ObjectProviderException(
+ "Attempt to clone object of type " + cloneable.getClass().getName() + " threw an exception.", e);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new ObjectProviderException(
+ String.format("Class %s does not have a clone() method (should never happen).", cloneable.getClass().getName()), e);
+ }
+ }
+
+//**********************************************************************************************************************
+// Getter/Setter Methods
+//**********************************************************************************************************************
+
+
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java
new file mode 100644
index 0000000..55ca010
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/ConstantProvider.java
@@ -0,0 +1,65 @@
+/*
+ * 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.provider;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+import java.io.Serializable;
+
+/**
+ * Always returns the same object.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class ConstantProvider<T> implements ObjectProvider<T>, Serializable
+{
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final T constant;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new ConstantProvider instance.
+ * @param constant
+ */
+ public ConstantProvider( T constant )
+ {
+ this.constant = constant;
+ }
+
+ //**********************************************************************************************************************
+ // ObjectProvider Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ public T getObject()
+ {
+ return constant;
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/provider/NullProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java
similarity index 64%
rename from src/main/java/org/apache/commons/proxy/provider/NullProvider.java
rename to core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java
index 7abee17..8aca99b 100644
--- a/src/main/java/org/apache/commons/proxy/provider/NullProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/NullProvider.java
@@ -1,37 +1,42 @@
-/*
- * 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.proxy.provider;
-
-/**
- * Always returns null.
- *
- * @author James Carman
- * @since 1.0
- */
-public class NullProvider extends ConstantProvider
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public NullProvider()
- {
- super(null);
- }
-}
-
+/*
+ * 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.provider;
+
+/**
+ * Always returns null.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class NullProvider<T> extends ConstantProvider<T>
+{
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ //**********************************************************************************************************************
+ // Constructors
+ //**********************************************************************************************************************
+
+ /**
+ * Create a new NullProvider instance.
+ */
+ public NullProvider()
+ {
+ super(null);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/ObjectProviderUtils.java b/core/src/main/java/org/apache/commons/proxy2/provider/ObjectProviderUtils.java
new file mode 100644
index 0000000..8b8204e
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/ObjectProviderUtils.java
@@ -0,0 +1,61 @@
+/*
+ * 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.provider;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+public final class ObjectProviderUtils
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Static Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public static <T> ObjectProvider<T> bean(Class<T> beanClass)
+ {
+ return new BeanProvider<T>(beanClass);
+ }
+
+ public static <T extends Cloneable> ObjectProvider<T> cloning(T prototype)
+ {
+ return new CloningProvider<T>(prototype);
+ }
+
+ public static <T> ObjectProvider<T> constant(T value)
+ {
+ return new ConstantProvider<T>(value);
+ }
+
+ public static <T> ObjectProvider<T> nullValue()
+ {
+ return new NullProvider<T>();
+ }
+
+ public static <T> ObjectProvider<T> singleton(ObjectProvider<T> inner)
+ {
+ return new SingletonProvider<T>(inner);
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ private ObjectProviderUtils()
+ {
+
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java b/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java
new file mode 100644
index 0000000..ded2907
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/ProviderDecorator.java
@@ -0,0 +1,80 @@
+/*
+ * 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.provider;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * Returns the result of the inner {@link ObjectProvider provider}. Subclasses can override the {@link #getObject()}
+ * method and decorate what comes back from the inner provider in some way (by {@link SingletonProvider caching it} for
+ * example).
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class ProviderDecorator<T> implements ObjectProvider<T>
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * The wrapped {@link ObjectProvider}.
+ */
+ private ObjectProvider<? extends T> inner;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Create a new ProviderDecorator instance.
+ *
+ * @param inner
+ */
+ public ProviderDecorator(ObjectProvider<? extends T> inner)
+ {
+ this.inner = inner;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// ObjectProvider Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ public T getObject()
+ {
+ return inner.getObject();
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Getter/Setter Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ protected ObjectProvider<? extends T> getInner()
+ {
+ return inner;
+ }
+
+ public void setInner(ObjectProvider<? extends T> inner)
+ {
+ this.inner = inner;
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/provider/SingletonProvider.java b/core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java
similarity index 77%
rename from src/main/java/org/apache/commons/proxy/provider/SingletonProvider.java
rename to core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java
index 45f0581..ceda06a 100644
--- a/src/main/java/org/apache/commons/proxy/provider/SingletonProvider.java
+++ b/core/src/main/java/org/apache/commons/proxy2/provider/SingletonProvider.java
@@ -1,64 +1,71 @@
-/*
- * 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.proxy.provider;
-
-import org.apache.commons.proxy.ObjectProvider;
-
-import java.io.Serializable;
-
-/**
- * Wraps another object provider, making sure to only call it once, returning the value returned from the wrapped
- * provider on all subsequent invocations.
- *
- * @author James Carman
- * @since 1.0
- */
-public class SingletonProvider extends ProviderDecorator implements Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private transient Object instance;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public SingletonProvider( ObjectProvider inner )
- {
- super(inner);
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- synchronized( this )
- {
- if( instance == null )
- {
- instance = super.getObject();
- }
- }
- return instance;
- }
-}
-
+/*
+ * 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.provider;
+
+import org.apache.commons.proxy2.ObjectProvider;
+
+/**
+ * Wraps another object provider, making sure to only call it once, returning the value returned from the wrapped
+ * provider on all subsequent invocations.
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public class SingletonProvider<T> extends ProviderDecorator<T>
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private T instance;
+
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ /**
+ * Create a new SingletonProvider instance.
+ *
+ * @param inner
+ */
+ public SingletonProvider(ObjectProvider<? extends T> inner)
+ {
+ super(inner);
+ }
+
+//**********************************************************************************************************************
+// ObjectProvider Implementation
+//**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ public T getObject()
+ {
+ synchronized (this)
+ {
+ if (instance == null)
+ {
+ instance = super.getObject();
+ // Garbage collection
+ setInner(null);
+ }
+ return instance;
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
new file mode 100644
index 0000000..48dafd8
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationBuilder.java
@@ -0,0 +1,265 @@
+/*
+ * 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 java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+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;
+import org.apache.commons.proxy2.ObjectProvider;
+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.ObjectProviderUtils;
+
+public class AnnotationBuilder<A extends Annotation> extends StubBuilder<A>
+{
+ // underlying proxyfactory implementation based on
+ // org.apache.commons.proxy2.jdk.JdkProxyFactory
+
+ private static class InterceptorInvocationHandler implements InvocationHandler, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final ObjectProvider<?> provider;
+ private final Interceptor methodInterceptor;
+
+ public InterceptorInvocationHandler(ObjectProvider<?> provider, Interceptor methodInterceptor)
+ {
+ this.provider = provider;
+ this.methodInterceptor = methodInterceptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ if (ProxyUtils.isHashCode(method))
+ {
+ return AnnotationUtils.hashCode((Annotation) proxy);
+ }
+ if (ProxyUtils.isEqualsMethod(method))
+ {
+ return args[0] instanceof Annotation
+ && AnnotationUtils.equals((Annotation) proxy, (Annotation) args[0]);
+ }
+ if ("toString".equals(method.getName()) && method.getParameterTypes().length == 0)
+ {
+ return AnnotationUtils.toString((Annotation) proxy);
+ }
+ final ReflectionInvocation invocation = new ReflectionInvocation(provider.getObject(), method, args);
+ return methodInterceptor.intercept(invocation);
+ }
+
+ }
+
+ private static class ReflectionInvocation implements Invocation, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Method method;
+ private final Object[] arguments;
+ private final Object target;
+
+ public ReflectionInvocation(Object target, Method method, Object[] arguments)
+ {
+ this.method = method;
+ this.arguments = (arguments == null ? ProxyUtils.EMPTY_ARGUMENTS : arguments);
+ this.target = target;
+ }
+
+ public Object[] getArguments()
+ {
+ return arguments;
+ }
+
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public Object getProxy()
+ {
+ return target;
+ }
+
+ public Object proceed() throws Throwable
+ {
+ try
+ {
+ return method.invoke(target, arguments);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw e.getTargetException();
+ }
+ }
+ }
+
+ private static final ProxyFactory PROXY_FACTORY = new AbstractProxyFactory()
+ {
+ @SuppressWarnings("unchecked")
+ public <T> T createInvokerProxy(ClassLoader classLoader, final Invoker invoker, Class<?>... proxyClasses)
+ {
+ return (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InvocationHandler()
+ {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ return invoker.invoke(proxy, method, args);
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+ Class<?>... proxyClasses)
+ {
+ return (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(
+ ObjectProviderUtils.constant(target), interceptor));
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T createDelegatorProxy(ClassLoader classLoader, final ObjectProvider<?> delegateProvider,
+ Class<?>... proxyClasses)
+ {
+ return (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(
+ delegateProvider, new Interceptor()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable
+ {
+ return invocation.proceed();
+ }
+ }));
+ }
+ };
+
+ private class MapAnnotationTrainer extends AnnotationTrainer<A>
+ {
+ final Map<String, ?> members;
+
+ MapAnnotationTrainer(Map<String, ?> members)
+ {
+ super(annotationType);
+ 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();
+ }
+
+ public static <A extends Annotation> AnnotationBuilder<A> of(Class<A> type)
+ {
+ return new AnnotationBuilder<A>(type, AnnotationInvoker.INSTANCE);
+ }
+
+ public static <A extends Annotation> AnnotationBuilder<A> of(Class<A> type, ObjectProvider<? extends A> provider)
+ {
+ return new AnnotationBuilder<A>(type, provider);
+ }
+
+ public static <A extends Annotation> AnnotationBuilder<A> of(Class<A> type, A target)
+ {
+ return new AnnotationBuilder<A>(type, target);
+ }
+
+ private final Class<A> annotationType;
+
+ private AnnotationBuilder(Class<A> type, Invoker invoker)
+ {
+ super(PROXY_FACTORY, type, invoker);
+ this.annotationType = type;
+ train(new AnnotationTypeTrainer<A>(type));
+ }
+
+ private AnnotationBuilder(Class<A> type, ObjectProvider<? extends A> provider)
+ {
+ super(PROXY_FACTORY, type, provider);
+ this.annotationType = type;
+ train(new AnnotationTypeTrainer<A>(type));
+ }
+
+ private AnnotationBuilder(Class<A> type, A target)
+ {
+ super(PROXY_FACTORY, type, target);
+ this.annotationType = type;
+ train(new AnnotationTypeTrainer<A>(type));
+ }
+
+ public AnnotationBuilder<A> withMembers(Map<String, ?> members)
+ {
+ return train(new MapAnnotationTrainer(members));
+ }
+
+ @Override
+ public <O> AnnotationBuilder<A> train(BaseTrainer<?, O> trainer)
+ {
+ return (AnnotationBuilder<A>) super.train(trainer);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationInvoker.java b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationInvoker.java
new file mode 100644
index 0000000..6e0b0e6
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationInvoker.java
@@ -0,0 +1,38 @@
+/*
+ * 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 java.lang.reflect.Method;
+
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ProxyUtils;
+
+public final class AnnotationInvoker implements Invoker
+{
+ private static final long serialVersionUID = 1L;
+
+ public static final AnnotationInvoker INSTANCE = new AnnotationInvoker();
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
+ final Object result = method.getDefaultValue();
+ return result == null && method.getReturnType().isPrimitive() ? ProxyUtils
+ .nullValue(method.getReturnType()) : result;
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTrainer.java
similarity index 65%
copy from src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
copy to core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTrainer.java
index f73551d..a808deb 100644
--- a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTrainer.java
@@ -15,17 +15,18 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.util;
+package org.apache.commons.proxy2.stub;
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface DuplicateEcho
+import java.lang.annotation.Annotation;
+
+public abstract class AnnotationTrainer<A extends Annotation> extends BaseAnnotationTrainer<AnnotationTrainer<A>, A>
{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
+ protected AnnotationTrainer() {
+ super();
+ }
- public String echoBack( String message );
+ protected AnnotationTrainer(Class<A> traineeType) {
+ super(traineeType);
+ }
+
}
diff --git a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTypeTrainer.java
similarity index 65%
copy from src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
copy to core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTypeTrainer.java
index f73551d..5754458 100644
--- a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/AnnotationTypeTrainer.java
@@ -15,17 +15,22 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.util;
+package org.apache.commons.proxy2.stub;
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface DuplicateEcho
+import java.lang.annotation.Annotation;
+
+class AnnotationTypeTrainer<R extends Annotation> extends AnnotationTrainer<R>
{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
- public String echoBack( String message );
-}
+ AnnotationTypeTrainer(Class<R> annotationType)
+ {
+ super(annotationType);
+ }
+
+ @Override
+ protected void train(R trainee)
+ {
+ when(trainee.annotationType()).thenReturn(traineeType);
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java b/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java
new file mode 100644
index 0000000..2a23fcf
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/BaseAnnotationTrainer.java
@@ -0,0 +1,111 @@
+/*
+ * 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 java.lang.annotation.Annotation;
+
+import org.apache.commons.proxy2.interceptor.InterceptorUtils;
+
+public abstract class BaseAnnotationTrainer<S extends BaseAnnotationTrainer<S, A>, A extends Annotation> extends
+ BaseTrainer<S, A>
+{
+ protected BaseAnnotationTrainer()
+ {
+ super();
+ }
+
+ protected BaseAnnotationTrainer(Class<A> traineeType)
+ {
+ super(traineeType);
+ }
+
+ protected class WhenAnnotation<R> extends WhenObject<R>
+ {
+ public S thenStub(Class<R> type)
+ {
+ trainingContext().push(type);
+ trainingContext().then(InterceptorUtils.constant(trainingContext().pop(AnnotationInvoker.INSTANCE)));
+ return self();
+ }
+
+ @Override
+ public S thenStub(BaseTrainer<?, R> trainer)
+ {
+ final R trainee = trainingContext().push(trainer.traineeType);
+ trainer.train(trainee);
+ trainingContext().then(InterceptorUtils.constant(trainingContext().pop(AnnotationInvoker.INSTANCE)));
+ return self();
+ }
+ }
+
+ protected class WhenAnnotationArray<R> extends WhenObjectArray<R>
+ {
+ protected WhenAnnotationArray(Class<? extends R> componentType)
+ {
+ super(componentType);
+ }
+
+ @Override
+ public StubAnnotationArrayBuilder<R> thenBuildArray()
+ {
+ return new StubAnnotationArrayBuilder<R>(componentType);
+ }
+ }
+
+ protected class StubAnnotationArrayBuilder<R> extends StubArrayBuilder<R>
+ {
+ private final BaseTrainer<?, R> annotationTypeTrainer;
+
+ private <N extends Annotation> StubAnnotationArrayBuilder(final Class<? extends R> componentType)
+ {
+ super(componentType);
+ @SuppressWarnings("unchecked")
+ final Class<N> annotationType = (Class<N>) componentType;
+ @SuppressWarnings("unchecked")
+ final BaseTrainer<?, R> annotationTypeTrainer = (BaseTrainer<?, R>) new AnnotationTypeTrainer<N>(
+ annotationType);
+ this.annotationTypeTrainer = annotationTypeTrainer;
+ }
+
+ @Override
+ public StubAnnotationArrayBuilder<R> addElement(BaseTrainer<?, R> trainer)
+ {
+ final R trainee = trainingContext().push(trainer.traineeType);
+
+ annotationTypeTrainer.train(trainee);
+ trainer.train(trainee);
+
+ elements.add(trainingContext().<R> pop());
+ return this;
+ }
+ }
+
+ @Override
+ public <R> WhenAnnotation<R> when(R expression)
+ {
+ return new WhenAnnotation<R>();
+ }
+
+ @Override
+ public <R> WhenAnnotationArray<R> when(R[] expression)
+ {
+ @SuppressWarnings("unchecked")
+ final Class<? extends R> componentType = (Class<? extends R>) expression.getClass().getComponentType();
+ return new WhenAnnotationArray<R>(componentType);
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java b/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java
new file mode 100644
index 0000000..8c386da
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/BaseTrainer.java
@@ -0,0 +1,357 @@
+/*
+ * 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 java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.reflect.TypeUtils;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.interceptor.InterceptorUtils;
+import org.apache.commons.proxy2.interceptor.matcher.ArgumentMatcher;
+import org.apache.commons.proxy2.interceptor.matcher.argument.ArgumentMatcherUtils;
+
+public abstract class BaseTrainer<S extends BaseTrainer<S, T>, T>
+{
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Fields
+ // ----------------------------------------------------------------------------------------------------------------------
+ public final Class<T> traineeType;
+
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Create a new {@link BaseTrainer} instance. This constructor should only
+ * be called by classes that explicitly assign the T parameter in the class
+ * definition. This should include basically any runtime-usable class.
+ */
+ protected BaseTrainer()
+ {
+ this(null);
+ }
+
+ protected BaseTrainer(Class<T> traineeType)
+ {
+ super();
+ if (traineeType != null)
+ {
+ this.traineeType = traineeType;
+ return;
+ }
+ @SuppressWarnings("unchecked")
+ final Class<T> resolvedVariable = (Class<T>) TypeUtils.getRawType(BaseTrainer.class.getTypeParameters()[1],
+ getClass());
+ Validate.isTrue(resolvedVariable != null, "Trainee type was not specified and could not be calculated for %s",
+ getClass());
+ this.traineeType = resolvedVariable;
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Abstract Methods
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ protected abstract void train(T trainee);
+
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Other Methods
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ protected <R> R any(Class<R> type)
+ {
+ return argThat(ArgumentMatcherUtils.<R> any());
+ }
+
+ protected <R> R eq(R value)
+ {
+ return argThat(ArgumentMatcherUtils.eq(value));
+ }
+
+ protected <R> R isInstance(Class<R> type)
+ {
+ return argThat(ArgumentMatcherUtils.<R> isA(type));
+ }
+
+ protected <R> R argThat(ArgumentMatcher<R> matcher)
+ {
+ trainingContext().record(matcher);
+ return null;
+ }
+
+ protected void thenThrow(Exception e)
+ {
+ trainingContext().then(InterceptorUtils.throwing(e));
+ }
+
+ protected void thenThrow(ObjectProvider<? extends Exception> provider)
+ {
+ trainingContext().then(InterceptorUtils.throwing(provider));
+ }
+
+ protected TrainingContext trainingContext()
+ {
+ return TrainingContext.current();
+ }
+
+ public <R> WhenObject<R> when(R expression)
+ {
+ return new WhenObject<R>();
+ }
+
+ public WhenClass when(Class<?> expression)
+ {
+ return new WhenClass();
+ }
+
+ public WhenByteArray when(byte[] expression)
+ {
+ return new WhenByteArray();
+ }
+
+ public WhenBooleanArray when(boolean[] expression)
+ {
+ return new WhenBooleanArray();
+ }
+
+ public WhenIntArray when(int[] expression)
+ {
+ return new WhenIntArray();
+ }
+
+ public WhenShortArray when(short[] expresssion)
+ {
+ return new WhenShortArray();
+ }
+
+ public WhenLongArray when(long[] expression)
+ {
+ return new WhenLongArray();
+ }
+
+ public WhenFloatArray when(float[] expression)
+ {
+ return new WhenFloatArray();
+ }
+
+ public WhenDoubleArray when(double[] expression)
+ {
+ return new WhenDoubleArray();
+ }
+
+ public <R> WhenObjectArray<R> when(R[] expression)
+ {
+ @SuppressWarnings("unchecked")
+ final Class<? extends R> componentType = (Class<? extends R>) expression.getClass().getComponentType();
+ return new WhenObjectArray<R>(componentType);
+ }
+
+ public WhenCharArray when(char[] expression)
+ {
+ return new WhenCharArray();
+ }
+
+ @SuppressWarnings("unchecked")
+ protected S self()
+ {
+ return (S) this;
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Inner Classes
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ protected abstract class BaseWhen<R>
+ {
+ public S thenThrow(Exception e)
+ {
+ return then(InterceptorUtils.throwing(e));
+ }
+
+ public S thenThrow(ObjectProvider<? extends Exception> provider)
+ {
+ return then(InterceptorUtils.throwing(provider));
+ }
+
+ public S thenAnswer(ObjectProvider<? extends R> provider)
+ {
+ return then(InterceptorUtils.provider(provider));
+ }
+
+ public S then(Interceptor interceptor)
+ {
+ trainingContext().then(interceptor);
+ return self();
+ }
+ }
+
+ protected class WhenBooleanArray extends BaseWhen<boolean[]>
+ {
+ public S thenReturn(boolean... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenByteArray extends BaseWhen<byte[]>
+ {
+ public S thenReturn(byte... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenCharArray extends BaseWhen<char[]>
+ {
+ public S thenReturn(char... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenDoubleArray extends BaseWhen<double[]>
+ {
+ public S thenReturn(double... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenFloatArray extends BaseWhen<float[]>
+ {
+ public S thenReturn(float... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenIntArray extends BaseWhen<int[]>
+ {
+ public S thenReturn(int... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenLongArray extends BaseWhen<long[]>
+ {
+ public S thenReturn(long... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+
+ protected class WhenObject<R> extends BaseWhen<R>
+ {
+ public S thenReturn(R value)
+ {
+ trainingContext().then(InterceptorUtils.constant(value));
+ return self();
+ }
+
+ public S thenStub(BaseTrainer<?, R> trainer)
+ {
+ final R trainee = trainingContext().push(trainer.traineeType);
+ trainer.train(trainee);
+ trainingContext().then(InterceptorUtils.constant(trainingContext().pop()));
+ return self();
+ }
+ }
+
+ /**
+ * Intermediate result of a when(Class) call. Provided because it is such a
+ * common case to have a mismatch between a declared Class<?> return type
+ * and the bound parameter of a class literal.
+ */
+ protected class WhenClass extends BaseWhen<Class<?>>
+ {
+ public S thenReturn(Class<?> value)
+ {
+ trainingContext().then(InterceptorUtils.constant(value));
+ return self();
+ }
+ }
+
+ protected class WhenObjectArray<R> extends BaseWhen<R[]>
+ {
+ protected final Class<? extends R> componentType;
+
+ protected WhenObjectArray(Class<? extends R> componentType)
+ {
+ this.componentType = componentType;
+ }
+
+ public S thenReturn(R... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+
+ public StubArrayBuilder<R> thenBuildArray()
+ {
+ return new StubArrayBuilder<R>(componentType);
+ }
+ }
+
+ protected class StubArrayBuilder<R>
+ {
+ protected final List<R> elements = new ArrayList<R>();
+ protected final Class<? extends R> componentType;
+
+ protected StubArrayBuilder(Class<? extends R> componentType)
+ {
+ this.componentType = componentType;
+ }
+
+ public StubArrayBuilder<R> addElement(BaseTrainer<?, R> trainer)
+ {
+ final R trainee = trainingContext().push(trainer.traineeType);
+ trainer.train(trainee);
+ elements.add(trainingContext().<R> pop());
+ return this;
+ }
+
+ public S build()
+ {
+ @SuppressWarnings("unchecked")
+ final R[] array = elements.toArray((R[]) Array.newInstance(componentType, elements.size()));
+ trainingContext().then(InterceptorUtils.constant(array));
+ return self();
+ }
+ }
+
+ protected class WhenShortArray extends BaseWhen<short[]>
+ {
+ public S thenReturn(short... values)
+ {
+ trainingContext().then(InterceptorUtils.constant(ArrayUtils.clone(values)));
+ return self();
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/StubBuilder.java b/core/src/main/java/org/apache/commons/proxy2/stub/StubBuilder.java
new file mode 100644
index 0000000..8b3b261
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/StubBuilder.java
@@ -0,0 +1,106 @@
+/*
+ * 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 java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.builder.Builder;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.interceptor.SwitchInterceptor;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.apache.commons.proxy2.provider.ConstantProvider;
+
+public class StubBuilder<T> implements Builder<T>
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final ProxyFactory proxyFactory;
+ private final T target;
+ private final SwitchInterceptor switchInterceptor = new SwitchInterceptor();
+ private final Set<Class<?>> proxyTypes = new HashSet<Class<?>>();
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public StubBuilder(ProxyFactory proxyFactory, Class<T> type)
+ {
+ this(proxyFactory, type, NullInvoker.INSTANCE);
+ }
+
+ public StubBuilder(ProxyFactory proxyFactory, Class<T> type, Invoker invoker)
+ {
+ this.proxyFactory = proxyFactory;
+ this.target = proxyFactory.createInvokerProxy(invoker, type);
+ this.proxyTypes.add(Validate.notNull(type));
+ }
+
+ public StubBuilder(ProxyFactory proxyFactory, Class<T> type, ObjectProvider<? extends T> provider)
+ {
+ this.proxyFactory = proxyFactory;
+ this.target = proxyFactory.createDelegatorProxy(provider, type);
+ this.proxyTypes.add(Validate.notNull(type));
+ }
+
+ public StubBuilder(ProxyFactory proxyFactory, Class<T> type, T target)
+ {
+ this.proxyFactory = proxyFactory;
+ this.target = proxyFactory.createDelegatorProxy(new ConstantProvider<T>(target), type);
+ this.proxyTypes.add(Validate.notNull(type));
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public T build()
+ {
+ return proxyFactory.createInterceptorProxy(target, switchInterceptor,
+ proxyTypes.toArray(ArrayUtils.EMPTY_CLASS_ARRAY));
+ }
+
+ public <O> StubBuilder<T> train(BaseTrainer<?, O> trainer)
+ {
+ final TrainingContext trainingContext = TrainingContext.join(proxyFactory);
+ try
+ {
+ final O trainee = trainingContext.push(trainer.traineeType, switchInterceptor);
+ trainer.train(trainee);
+ proxyTypes.add(trainer.traineeType);
+ }
+ finally
+ {
+ trainingContext.part();
+ }
+ return this;
+ }
+
+ public StubBuilder<T> addProxyTypes(Class<?>... proxyTypes)
+ {
+ Collections.addAll(this.proxyTypes, Validate.noNullElements(proxyTypes));
+ return this;
+ }
+}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/StubInterceptorBuilder.java b/core/src/main/java/org/apache/commons/proxy2/stub/StubInterceptorBuilder.java
new file mode 100644
index 0000000..dff59f9
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/StubInterceptorBuilder.java
@@ -0,0 +1,65 @@
+/*
+ * 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.Interceptor;
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.interceptor.SwitchInterceptor;
+
+public class StubInterceptorBuilder
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final ProxyFactory proxyFactory;
+ private final SwitchInterceptor interceptor = new SwitchInterceptor();
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public StubInterceptorBuilder(ProxyFactory proxyFactory)
+ {
+ this.proxyFactory = proxyFactory;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public Interceptor build()
+ {
+ return interceptor;
+ }
+
+ public <T> StubInterceptorBuilder train(Trainer<T> trainer)
+ {
+ final TrainingContext trainingContext = TrainingContext.join(proxyFactory);
+ try
+ {
+ final T stub = trainingContext.push(trainer.traineeType, interceptor);
+ trainer.train(stub);
+ }
+ finally
+ {
+ trainingContext.part();
+ }
+ return this;
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java b/core/src/main/java/org/apache/commons/proxy2/stub/Trainer.java
similarity index 65%
copy from src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
copy to core/src/main/java/org/apache/commons/proxy2/stub/Trainer.java
index f73551d..d0962bc 100644
--- a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/Trainer.java
@@ -15,17 +15,16 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.util;
+package org.apache.commons.proxy2.stub;
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface DuplicateEcho
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
+public abstract class Trainer<T> extends BaseTrainer<Trainer<T>, T> {
- public String echoBack( String message );
+ protected Trainer() {
+ super();
+ }
+
+ protected Trainer(Class<T> traineeType) {
+ super(traineeType);
+ }
+
}
diff --git a/core/src/main/java/org/apache/commons/proxy2/stub/TrainingContext.java b/core/src/main/java/org/apache/commons/proxy2/stub/TrainingContext.java
new file mode 100644
index 0000000..c0ad666
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/TrainingContext.java
@@ -0,0 +1,257 @@
+package org.apache.commons.proxy2.stub;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.proxy2.*;
+import org.apache.commons.proxy2.interceptor.SwitchInterceptor;
+import org.apache.commons.proxy2.interceptor.matcher.ArgumentMatcher;
+import org.apache.commons.proxy2.interceptor.matcher.InvocationMatcher;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.apache.commons.proxy2.invoker.RecordedInvocation;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.*;
+
+class TrainingContext
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private static final ThreadLocal<TrainingContext> TRAINING_CONTEXT = new ThreadLocal<TrainingContext>();
+
+ private final ProxyFactory proxyFactory;
+
+ private Deque<TrainingContextFrame<?>> frameDeque = new LinkedList<TrainingContextFrame<?>>();
+
+ private final TrainingContext resume;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Static Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ static TrainingContext current()
+ {
+ return TRAINING_CONTEXT.get();
+ }
+
+ static synchronized TrainingContext join(ProxyFactory proxyFactory)
+ {
+ final TrainingContext context = new TrainingContext(proxyFactory);
+ TRAINING_CONTEXT.set(context);
+ return context;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ private TrainingContext(ProxyFactory proxyFactory)
+ {
+ this.proxyFactory = proxyFactory;
+ this.resume = current();
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ void part()
+ {
+ synchronized (TRAINING_CONTEXT)
+ {
+ if (resume == null)
+ {
+ TRAINING_CONTEXT.remove();
+ }
+ else
+ {
+ TRAINING_CONTEXT.set(resume);
+ }
+ }
+ }
+
+ private TrainingContextFrame<?> peek()
+ {
+ return frameDeque.peek();
+ }
+
+ <T> T pop()
+ {
+ return pop(NullInvoker.INSTANCE);
+ }
+
+ <T> T pop(Invoker invoker)
+ {
+ final TrainingContextFrame<?> frame = frameDeque.pop();
+ return proxyFactory.createInterceptorProxy(
+ proxyFactory.createInvokerProxy(invoker, frame.type),
+ frame.stubInterceptor,
+ frame.type);
+ }
+
+ <T> T push(Class<T> type)
+ {
+ return push(type, new SwitchInterceptor());
+ }
+
+ <T> T push(Class<T> type, SwitchInterceptor switchInterceptor)
+ {
+ TrainingContextFrame<T> frame = new TrainingContextFrame<T>(type, switchInterceptor);
+ Invoker invoker = new TrainingInvoker(frame);
+ frameDeque.push(frame);
+ return proxyFactory.createInvokerProxy(invoker, type);
+ }
+
+ void record(ArgumentMatcher<?> argumentMatcher)
+ {
+ peek().argumentMatchers.add(argumentMatcher);
+ }
+
+ void then(Interceptor interceptor)
+ {
+ peek().then(interceptor);
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Inner Classes
+//----------------------------------------------------------------------------------------------------------------------
+
+ private static final class ExactArgumentsMatcher implements InvocationMatcher
+ {
+ private final RecordedInvocation recordedInvocation;
+
+ private ExactArgumentsMatcher(RecordedInvocation recordedInvocation)
+ {
+ this.recordedInvocation = recordedInvocation;
+ }
+
+ @Override
+ public boolean matches(Invocation invocation)
+ {
+ return invocation.getMethod().equals(recordedInvocation.getInvokedMethod()) &&
+ Arrays.deepEquals(invocation.getArguments(), recordedInvocation.getArguments());
+ }
+ }
+
+ private static final class MatchingArgumentsMatcher implements InvocationMatcher
+ {
+ private final RecordedInvocation recordedInvocation;
+ private final ArgumentMatcher<?>[] matchers;
+
+ private MatchingArgumentsMatcher(RecordedInvocation recordedInvocation, ArgumentMatcher<?>[] matchers)
+ {
+ this.recordedInvocation = recordedInvocation;
+ this.matchers = ArrayUtils.clone(matchers);
+ }
+
+ @Override
+ public boolean matches(Invocation invocation)
+ {
+ return invocation.getMethod().equals(recordedInvocation.getInvokedMethod()) &&
+ allArgumentsMatch(invocation.getArguments());
+ }
+
+ private boolean allArgumentsMatch(Object[] arguments)
+ {
+ for (int i = 0; i < arguments.length; i++)
+ {
+ Object argument = arguments[i];
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ final boolean matches = ((ArgumentMatcher) matchers[i]).matches(argument);
+ if (!matches)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private static final class TrainingContextFrame<T>
+ {
+ private final String id = UUID.randomUUID().toString();
+
+ private final SwitchInterceptor stubInterceptor;
+
+ private final List<ArgumentMatcher<?>> argumentMatchers = new LinkedList<ArgumentMatcher<?>>();
+
+ private InvocationMatcher matcher = null;
+
+ private final Class<T> type;
+
+ private TrainingContextFrame(Class<T> type, SwitchInterceptor stubInterceptor)
+ {
+ this.type = type;
+ this.stubInterceptor = stubInterceptor;
+ }
+
+ private String getId()
+ {
+ return id;
+ }
+
+ void then(Interceptor thenInterceptor)
+ {
+ if (matcher == null)
+ {
+ throw new IllegalStateException("No when!");
+ }
+ stubInterceptor.when(matcher).then(thenInterceptor);
+ matcher = null;
+ }
+
+ void methodInvoked(Method method, Object[] arguments)
+ {
+ final ArgumentMatcher<?>[] matchersArray = argumentMatchers.toArray(new ArgumentMatcher[argumentMatchers.size()]);
+ argumentMatchers.clear();
+ final RecordedInvocation invocation = new RecordedInvocation(method, arguments);
+ if (ArrayUtils.isEmpty(matchersArray))
+ {
+ this.matcher = new ExactArgumentsMatcher(invocation);
+ }
+ else if (matchersArray.length == arguments.length)
+ {
+ this.matcher = new MatchingArgumentsMatcher(invocation, matchersArray);
+ }
+ else
+ {
+ throw new IllegalStateException("Either use exact arguments or argument matchers, but not both.");
+ }
+ }
+ }
+
+ private static final class TrainingInvoker implements Invoker
+ {
+ private static final long serialVersionUID = 1L;
+
+ private final String id;
+
+ private TrainingInvoker(TrainingContextFrame<?> frame)
+ {
+ this.id = frame.getId();
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable
+ {
+ final TrainingContextFrame<?> frame = current().peek();
+ if (!frame.getId().equals(id))
+ {
+ throw new IllegalStateException("Wrong stub!");
+ }
+ else
+ {
+ frame.methodInvoked(method, arguments);
+ }
+
+ final Class<?> type = method.getReturnType();
+
+ if (Object[].class.isAssignableFrom(type))
+ {
+ return Array.newInstance(type.getComponentType(), 0);
+ }
+ return ProxyUtils.nullValue(type);
+ }
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java b/core/src/main/java/org/apache/commons/proxy2/stub/package-info.java
similarity index 65%
copy from src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
copy to core/src/main/java/org/apache/commons/proxy2/stub/package-info.java
index f73551d..4bcf681 100644
--- a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
+++ b/core/src/main/java/org/apache/commons/proxy2/stub/package-info.java
@@ -15,17 +15,7 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.util;
-
/**
- * @author James Carman
- * @since 1.0
+ * Contains mechanisms for stubbing behavior on {@link org.apache.commons.proxy2.ProxyFactory}-generated proxy objects.
*/
-public interface DuplicateEcho
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public String echoBack( String message );
-}
+package org.apache.commons.proxy2.stub;
\ No newline at end of file
diff --git a/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java b/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java
new file mode 100644
index 0000000..9a65855
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/AbstractProxyFactoryTestCase.java
@@ -0,0 +1,396 @@
+/*
+ * 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;
+
+import org.apache.commons.proxy2.provider.BeanProvider;
+import org.apache.commons.proxy2.provider.ConstantProvider;
+import org.apache.commons.proxy2.provider.SingletonProvider;
+import org.apache.commons.proxy2.util.*;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractProxyFactoryTestCase extends AbstractTestCase
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private static final Class<?>[] ECHO_ONLY = new Class[]{Echo.class};
+ protected final ProxyFactory factory;
+ private static final Class<?>[] COMPARABLE_ONLY = new Class[]{Comparable.class};
+
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ protected AbstractProxyFactoryTestCase()
+ {
+ final ServiceLoader<ProxyFactory> serviceLoader = ServiceLoader.load(ProxyFactory.class);
+ Iterator<ProxyFactory> iter = serviceLoader.iterator();
+ if (iter.hasNext())
+ {
+ this.factory = iter.next();
+ }
+ else
+ {
+ throw new RuntimeException("Unable to find proxy factory implementation.");
+ }
+
+ }
+
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ private ObjectProvider<Echo> createSingletonEcho()
+ {
+ return new SingletonProvider<Echo>(new BeanProvider<Echo>(EchoImpl.class));
+ }
+
+ @Test
+ public void testInterceptorHashCode()
+ {
+ final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
+ }
+
+ @Test
+ public void testInvokerHashCode() throws Exception
+ {
+ final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+ assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
+ }
+
+ @Test
+ public void testDelegatorHashCode() throws Exception
+ {
+ final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+ assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
+ }
+
+ @Test
+ public void testInterceptorEquals()
+ {
+ final Date date = new Date();
+ final Comparable<?> proxy1 = factory.createInterceptorProxy(date,
+ new NoOpMethodInterceptor(), COMPARABLE_ONLY);
+ final Comparable<?> proxy2 = factory.createInterceptorProxy(date,
+ new NoOpMethodInterceptor(), COMPARABLE_ONLY);
+ assertEquals(proxy1, proxy1);
+ assertFalse(proxy1.equals(proxy2));
+ assertFalse(proxy2.equals(proxy1));
+ }
+
+ @Test
+ public void testInvokerEquals() throws Exception
+ {
+ final Comparable<?> proxy1 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
+ final Comparable<?> proxy2 = factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
+ assertEquals(proxy1, proxy1);
+ assertFalse(proxy1.equals(proxy2));
+ assertFalse(proxy2.equals(proxy1));
+ }
+
+ @Test
+ public void testDelegatorEquals() throws Exception
+ {
+ final Date date = new Date();
+ final Comparable<?> proxy1 = factory.createDelegatorProxy(new ConstantProvider<Date>(date),
+ COMPARABLE_ONLY);
+ final Comparable<?> proxy2 = factory.createDelegatorProxy(new ConstantProvider<Date>(date),
+ COMPARABLE_ONLY);
+ assertEquals(proxy1, proxy1);
+ assertFalse(proxy1.equals(proxy2));
+ assertFalse(proxy2.equals(proxy1));
+ }
+
+ @Test
+ public void testBooleanInterceptorParameter()
+ {
+ final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new InterceptorTester(), ECHO_ONLY);
+ assertFalse(echo.echoBack(false));
+ assertTrue(echo.echoBack(true));
+ }
+
+ @Test
+ public void testCanProxy()
+ {
+ assertTrue(factory.canProxy(Echo.class));
+ assertFalse(factory.canProxy(EchoImpl.class));
+ }
+
+ @Test
+ public void testChangingArguments()
+ {
+ final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new ChangeArgumentInterceptor(), ECHO_ONLY);
+ assertEquals("something different", proxy.echoBack("whatever"));
+ }
+
+ @Test
+ public void testCreateDelegatingProxy()
+ {
+ final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
+ echo.echo();
+ assertEquals("message", echo.echoBack("message"));
+ assertEquals("ab", echo.echoBack("a", "b"));
+ }
+
+ @Test
+ public void testCreateInterceptorProxy()
+ {
+ final Echo target = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
+ final Echo proxy = factory.createInterceptorProxy(target, new SuffixInterceptor(" suffix"), ECHO_ONLY);
+ proxy.echo();
+ assertEquals("message suffix", proxy.echoBack("message"));
+ }
+
+ @Test
+ public void testDelegatingProxyClassCaching() throws Exception
+ {
+ final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+ final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+ assertNotSame(proxy1, proxy2);
+ assertSame(proxy1.getClass(), proxy2.getClass());
+ }
+
+ @Test
+ public void testDelegatingProxyInterfaceOrder()
+ {
+ final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), Echo.class, DuplicateEcho.class);
+ final List<Class<?>> expected = new LinkedList<Class<?>>(Arrays.<Class<?>>asList(Echo.class, DuplicateEcho.class));
+ final List<Class<?>> actual = new LinkedList<Class<?>>(Arrays.asList(echo.getClass().getInterfaces()));
+ actual.retainAll(expected); // Doesn't alter order!
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testDelegatingProxySerializable() throws Exception
+ {
+ final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+ assertSerializable(proxy);
+ }
+
+ @Test
+ public void testInterceptingProxyClassCaching() throws Exception
+ {
+ final Echo proxy1 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ final Echo proxy2 = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ assertNotSame(proxy1, proxy2);
+ assertSame(proxy1.getClass(), proxy2.getClass());
+ }
+
+ @Test
+ public void testInterceptingProxySerializable() throws Exception
+ {
+ final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ assertSerializable(proxy);
+ }
+
+ @Test(expected = IOException.class)
+ public void testInterceptorProxyWithCheckedException() throws Exception
+ {
+ final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ proxy.ioException();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInterceptorProxyWithUncheckedException() throws Exception
+ {
+ final Echo proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ proxy.illegalArgument();
+ }
+
+ @Test
+ public void testInterfaceHierarchies()
+ {
+ final SortedSet<String> set = factory.createDelegatorProxy(new ConstantProvider<SortedSet<String>>(new TreeSet<String>()), SortedSet.class);
+ set.add("Hello");
+ }
+
+ @Test
+ public void testInvokerProxy() throws Exception
+ {
+ final InvokerTester tester = new InvokerTester();
+ final Echo echo = factory.createInvokerProxy(tester, ECHO_ONLY);
+ echo.echoBack("hello");
+ assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
+ assertSame(echo, tester.proxy);
+ assertNotNull(tester.args);
+ assertEquals(1, tester.args.length);
+ assertEquals("hello", tester.args[0]);
+ }
+
+ @Test
+ public void testInvokerProxyClassCaching() throws Exception
+ {
+ final Echo proxy1 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+ final Echo proxy2 = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+ assertNotSame(proxy1, proxy2);
+ assertSame(proxy1.getClass(), proxy2.getClass());
+ }
+
+ @Test
+ public void testInvokerProxySerializable() throws Exception
+ {
+ final Echo proxy = factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
+ assertSerializable(proxy);
+ }
+
+ @Test
+ public void testMethodInvocationClassCaching() throws Exception
+ {
+ final InterceptorTester tester = new InterceptorTester();
+ final EchoImpl target = new EchoImpl();
+ final Echo proxy1 = factory.createInterceptorProxy(target, tester, ECHO_ONLY);
+ final Echo proxy2 = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);
+ proxy1.echoBack("hello1");
+ final Class<?> invocationClass1 = tester.invocationClass;
+ proxy2.echoBack("hello2");
+ assertSame(invocationClass1, tester.invocationClass);
+ }
+
+ @Test
+ public void testMethodInvocationDuplicateMethods() throws Exception
+ {
+ final InterceptorTester tester = new InterceptorTester();
+ final EchoImpl target = new EchoImpl();
+ final Echo proxy = factory.createInterceptorProxy(target, tester, Echo.class, DuplicateEcho.class);
+ proxy.echoBack("hello");
+ assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
+ }
+
+ @Test
+ public void testMethodInvocationImplementation() throws Exception
+ {
+ final InterceptorTester tester = new InterceptorTester();
+ final EchoImpl target = new EchoImpl();
+ final Echo proxy = factory.createInterceptorProxy(target, tester, ECHO_ONLY);
+ proxy.echo();
+ assertNotNull(tester.arguments);
+ assertEquals(0, tester.arguments.length);
+ assertEquals(Echo.class.getMethod("echo"), tester.method);
+ assertSame(proxy, tester.proxy);
+ proxy.echoBack("Hello");
+ assertNotNull(tester.arguments);
+ assertEquals(1, tester.arguments.length);
+ assertEquals("Hello", tester.arguments[0]);
+ assertEquals(Echo.class.getMethod("echoBack", String.class), tester.method);
+ proxy.echoBack("Hello", "World");
+ assertNotNull(tester.arguments);
+ assertEquals(2, tester.arguments.length);
+ assertEquals("Hello", tester.arguments[0]);
+ assertEquals("World", tester.arguments[1]);
+ assertEquals(Echo.class.getMethod("echoBack", String.class, String.class), tester.method);
+ }
+
+ @Test
+ public void testPrimitiveParameter()
+ {
+ final Echo echo = factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
+ assertEquals(1, echo.echoBack(1));
+ }
+
+ @Test(expected = IOException.class)
+ public void testProxyWithCheckedException() throws Exception
+ {
+ final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+ proxy.ioException();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testProxyWithUncheckedException() throws Exception
+ {
+ final Echo proxy = factory.createDelegatorProxy(new ConstantProvider<Echo>(new EchoImpl()), Echo.class);
+ proxy.illegalArgument();
+ }
+
+ @Test
+ public void testWithNonAccessibleTargetType()
+ {
+ final Echo proxy = factory.createInterceptorProxy(new PrivateEcho(), new NoOpMethodInterceptor(), ECHO_ONLY);
+ proxy.echo();
+ }
+
+//**********************************************************************************************************************
+// Inner Classes
+//**********************************************************************************************************************
+
+ private static class ChangeArgumentInterceptor implements Interceptor
+ {
+ public Object intercept(Invocation methodInvocation) throws Throwable
+ {
+ methodInvocation.getArguments()[0] = "something different";
+ return methodInvocation.proceed();
+ }
+ }
+
+ protected static class InterceptorTester implements Interceptor
+ {
+ private Object[] arguments;
+ private Method method;
+ private Object proxy;
+ private Class<?> invocationClass;
+
+ public Object intercept(Invocation methodInvocation) throws Throwable
+ {
+ arguments = methodInvocation.getArguments();
+ method = methodInvocation.getMethod();
+ proxy = methodInvocation.getProxy();
+ invocationClass = methodInvocation.getClass();
+ return methodInvocation.proceed();
+ }
+ }
+
+ protected static class InvokerTester implements Invoker
+ {
+ private Object method;
+ private Object[] args;
+ private Object proxy;
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ this.proxy = proxy;
+ this.method = method;
+ this.args = args;
+ return null;
+ }
+ }
+
+ protected static class NoOpMethodInterceptor implements Interceptor, Serializable
+ {
+ public Object intercept(Invocation methodInvocation) throws Throwable
+ {
+ return methodInvocation.proceed();
+ }
+ }
+
+ private static class PrivateEcho extends EchoImpl
+ {
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java b/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java
new file mode 100644
index 0000000..7146ae5
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/AbstractSubclassingProxyFactoryTestCase.java
@@ -0,0 +1,214 @@
+/*
+ * 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;
+
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.apache.commons.proxy2.provider.ConstantProvider;
+import org.apache.commons.proxy2.util.AbstractEcho;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.junit.Test;
+
+import java.util.Date;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractSubclassingProxyFactoryTestCase extends AbstractProxyFactoryTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private static final Class<?>[] DATE_ONLY = new Class[]{Date.class};
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testCanProxy()
+ {
+ assertTrue(factory.canProxy(new Class[]{Echo.class}));
+ assertTrue(factory.canProxy(new Class[]{EchoImpl.class}));
+ assertFalse(factory.canProxy(new Class[]{FinalEcho.class}));
+ assertTrue(factory.canProxy(new Class[]{FinalMethodEcho.class, Echo.class}));
+ assertFalse(factory.canProxy(new Class[]{NoDefaultConstructorEcho.class}));
+ assertTrue(factory.canProxy(new Class[]{ProtectedConstructorEcho.class}));
+ assertFalse(factory.canProxy(new Class[]{InvisibleEcho.class}));
+ assertFalse(factory.canProxy(new Class[]{Echo.class, EchoImpl.class, String.class}));
+ }
+
+ @Test
+ public void testDelegatorEquals() throws Exception
+ {
+ final EqualsEcho echo = new EqualsEcho("text");
+ final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo),
+ new Class[]{EqualsEcho.class});
+ final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo),
+ new Class[]{EqualsEcho.class});
+ assertEquals(proxy1, proxy1);
+ assertFalse(proxy1.equals(proxy2));
+ assertFalse(proxy2.equals(proxy1));
+ }
+
+ @Test(expected = ProxyFactoryException.class)
+ public void testDelegatorWithMultipleSuperclasses()
+ {
+ factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()),
+ new Class[]{EchoImpl.class, String.class});
+ }
+
+ @Test
+ public void testDelegatorWithSuperclass()
+ {
+ final Echo echo = factory
+ .createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[]{Echo.class, EchoImpl.class});
+ assertTrue(echo instanceof EchoImpl);
+ }
+
+ @Test
+ public void testInterceptorEquals()
+ {
+ final EqualsEcho echo = new EqualsEcho("text");
+ final Echo proxy1 = factory.createInterceptorProxy(echo,
+ new NoOpMethodInterceptor(), new Class[]{EqualsEcho.class});
+ final Echo proxy2 = factory.createInterceptorProxy(echo,
+ new NoOpMethodInterceptor(), new Class[]{EqualsEcho.class});
+ assertEquals(proxy1, proxy1);
+ assertFalse(proxy1.equals(proxy2));
+ assertFalse(proxy2.equals(proxy1));
+ }
+
+ @Test(expected = ProxyFactoryException.class)
+ public void testInterceptorWithMultipleSuperclasses()
+ {
+ factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(),
+ new Class[]{EchoImpl.class, String.class});
+ }
+
+ @Test
+ public void testInterceptorWithSuperclass()
+ {
+ final Echo echo = factory
+ .createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[]{Echo.class, EchoImpl.class});
+ assertTrue(echo instanceof EchoImpl);
+ }
+
+ @Test(expected = ProxyFactoryException.class)
+ public void testInvocationHandlerWithMultipleSuperclasses()
+ {
+ factory.createInvokerProxy(new NullInvoker(),
+ new Class[]{EchoImpl.class, String.class});
+ }
+
+ @Test
+ public void testInvokerEquals() throws Exception
+ {
+ final Date proxy1 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);
+ final Date proxy2 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);
+ assertEquals(proxy1, proxy1);
+ assertFalse(proxy1.equals(proxy2));
+ assertFalse(proxy2.equals(proxy1));
+ }
+
+ @Test
+ public void testInvokerWithSuperclass()
+ {
+ final Echo echo = factory
+ .createInvokerProxy(new NullInvoker(), new Class[]{Echo.class, EchoImpl.class});
+ assertTrue(echo instanceof EchoImpl);
+ }
+
+ @Test
+ public void testProxiesWithClashingFinalMethodInSuperclass()
+ {
+ final Class<?>[] proxyClasses = new Class[]{Echo.class, FinalMethodEcho.class};
+ Echo proxy = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), proxyClasses);
+ assertEquals("final", proxy.echoBack("echo"));
+
+ proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), proxyClasses);
+ assertEquals("final", proxy.echoBack("echo"));
+
+ proxy = factory.createInvokerProxy(new NullInvoker(), proxyClasses);
+ assertEquals("final", proxy.echoBack("echo"));
+ }
+
+ @Test
+ public void testWithAbstractSuperclass()
+ {
+ final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[]{AbstractEcho.class});
+ assertEquals("hello", echo.echoBack("hello"));
+ assertEquals("helloworld", echo.echoBack("hello", "world"));
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Inner Classes
+//----------------------------------------------------------------------------------------------------------------------
+
+ public static class EqualsEcho extends EchoImpl
+ {
+ @SuppressWarnings("unused")
+ private final String text;
+
+ protected EqualsEcho()
+ {
+ this("testing");
+ }
+
+ public EqualsEcho(String text)
+ {
+ this.text = text;
+ }
+ }
+
+ public static final class FinalEcho extends EchoImpl
+ {
+ }
+
+ public static class FinalMethodEcho extends EchoImpl
+ {
+ public final String echoBack(String message)
+ {
+ return "final";
+ }
+ }
+
+ private static class InvisibleEcho extends EchoImpl
+ {
+ }
+
+ public static class NoDefaultConstructorEcho extends EchoImpl
+ {
+ public NoDefaultConstructorEcho(String param)
+ {
+ }
+ }
+
+ public static class ProtectedConstructorEcho extends EchoImpl
+ {
+ protected ProtectedConstructorEcho()
+ {
+ }
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/TestProxyUtils.java b/core/src/test/java/org/apache/commons/proxy2/ProxyUtilsTest.java
similarity index 67%
rename from src/test/java/org/apache/commons/proxy/TestProxyUtils.java
rename to core/src/test/java/org/apache/commons/proxy2/ProxyUtilsTest.java
index 5dcf0ff..e2f25f1 100644
--- a/src/test/java/org/apache/commons/proxy/TestProxyUtils.java
+++ b/core/src/test/java/org/apache/commons/proxy2/ProxyUtilsTest.java
@@ -15,19 +15,24 @@
* limitations under the License.
*/
-package org.apache.commons.proxy;
+package org.apache.commons.proxy2;
-import junit.framework.TestCase;
-import org.apache.commons.proxy.factory.javassist.JavassistProxyFactory;
-import org.apache.commons.proxy.util.DuplicateEcho;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.DuplicateEcho;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Properties;
-public class TestProxyUtils extends TestCase
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class ProxyUtilsTest extends AbstractTestCase
{
//**********************************************************************************************************************
// Fields
@@ -39,42 +44,47 @@
// Other Methods
//**********************************************************************************************************************
- protected void setUp() throws Exception
+ @Before
+ public void setUp() throws Exception
{
prevProperties = System.getProperties();
System.setProperties(new Properties());
}
- protected void tearDown() throws Exception
+ @After
+ public void tearDown() throws Exception
{
System.setProperties(prevProperties);
}
- public void testCreateNullObject() throws Exception
+ @Test
+ public void testNullValue()
{
- final Echo nullEcho = ( Echo ) ProxyUtils
- .createNullObject(new JavassistProxyFactory(), new Class[] {Echo.class});
- assertNull(nullEcho.echoBack("hello"));
- assertNull(nullEcho.echoBack("hello", "world"));
- assertEquals(( int ) 0, nullEcho.echoBack(12345));
+ assertNullValue(null, String.class);
+ assertNullValue(( char ) 0, Character.TYPE);
+ assertNullValue(0, Integer.TYPE);
+ assertNullValue(( long ) 0, Long.TYPE);
+ assertNullValue(( short ) 0, Short.TYPE);
+ assertNullValue(( double ) 0, Double.TYPE);
+ assertNullValue(( float ) 0, Float.TYPE);
+ assertNullValue(false, Boolean.TYPE);
+ assertNullValue(( byte ) 0, Byte.TYPE);
}
- public void testCreateNullObjectWithClassLoader() throws Exception
+ private void assertNullValue( Object expected, Class<?> type )
{
- final Echo nullEcho = ( Echo ) ProxyUtils.createNullObject(new JavassistProxyFactory(),
- Echo.class.getClassLoader(),
- new Class[] {Echo.class});
- assertNull(nullEcho.echoBack("hello"));
- assertNull(nullEcho.echoBack("hello", "world"));
- assertEquals(( int ) 0, nullEcho.echoBack(12345));
+ assertEquals(expected, ProxyUtils.nullValue(type));
}
+ @Test
public void testGetAllInterfaces()
{
assertNull(ProxyUtils.getAllInterfaces(null));
- assertEquals(Arrays.asList(new Class[] {DuplicateEcho.class, Serializable.class, Echo.class}), Arrays.asList(ProxyUtils.getAllInterfaces(EchoImpl.class)));
+ assertEquals(Arrays.asList(new Class[] {DuplicateEcho.class, Serializable.class, Echo.class}),
+ Arrays.asList(ProxyUtils.getAllInterfaces(EchoImpl.class)));
}
+ @Test
public void testGetJavaClassName() throws Exception
{
assertEquals("java.lang.Object[]", ProxyUtils.getJavaClassName(Object[].class));
diff --git a/src/test/java/org/apache/commons/proxy/exception/AbstractExceptionClassTestCase.java b/core/src/test/java/org/apache/commons/proxy2/exception/AbstractExceptionClassTestCase.java
similarity index 88%
rename from src/test/java/org/apache/commons/proxy/exception/AbstractExceptionClassTestCase.java
rename to core/src/test/java/org/apache/commons/proxy2/exception/AbstractExceptionClassTestCase.java
index 343ddd6..f065412 100644
--- a/src/test/java/org/apache/commons/proxy/exception/AbstractExceptionClassTestCase.java
+++ b/core/src/test/java/org/apache/commons/proxy2/exception/AbstractExceptionClassTestCase.java
@@ -15,27 +15,29 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.exception;
+package org.apache.commons.proxy2.exception;
-import junit.framework.TestCase;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.junit.Test;
+import static org.junit.Assert.*;
/**
* @author James Carman
* @since 1.0
*/
-public abstract class AbstractExceptionClassTestCase extends TestCase
+public abstract class AbstractExceptionClassTestCase extends AbstractTestCase
{
//**********************************************************************************************************************
// Fields
//**********************************************************************************************************************
- private final Class exceptionClass;
+ private final Class<?> exceptionClass;
//**********************************************************************************************************************
// Constructors
//**********************************************************************************************************************
- public AbstractExceptionClassTestCase( Class exceptionClass )
+ public AbstractExceptionClassTestCase( Class<?> exceptionClass )
{
this.exceptionClass = exceptionClass;
}
@@ -44,6 +46,7 @@
// Other Methods
//**********************************************************************************************************************
+ @Test
public void testCauseOnlyConstructor() throws Exception
{
final Exception cause = new Exception();
@@ -52,6 +55,7 @@
assertEquals(cause, e.getCause());
}
+ @Test
public void testMessageAndCauseConstructor() throws Exception
{
final Exception cause = new Exception();
@@ -61,6 +65,7 @@
assertEquals(cause, e.getCause());
}
+ @Test
public void testMessageOnlyConstructor() throws Exception
{
final String message = "message";
@@ -69,6 +74,7 @@
assertNull(e.getCause());
}
+ @Test
public void testNoArgConstructor() throws Exception
{
Exception e = ( Exception ) exceptionClass.getConstructor(new Class[] {}).newInstance(new Object[] {});
diff --git a/src/test/java/org/apache/commons/proxy/exception/TestDelegateProviderException.java b/core/src/test/java/org/apache/commons/proxy2/exception/DelegateProviderExceptionTest.java
similarity index 87%
rename from src/test/java/org/apache/commons/proxy/exception/TestDelegateProviderException.java
rename to core/src/test/java/org/apache/commons/proxy2/exception/DelegateProviderExceptionTest.java
index 45af58c..d1c41ac 100644
--- a/src/test/java/org/apache/commons/proxy/exception/TestDelegateProviderException.java
+++ b/core/src/test/java/org/apache/commons/proxy2/exception/DelegateProviderExceptionTest.java
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.exception;
+package org.apache.commons.proxy2.exception;
-public class TestDelegateProviderException extends AbstractExceptionClassTestCase
+public class DelegateProviderExceptionTest extends AbstractExceptionClassTestCase
{
//**********************************************************************************************************************
// Constructors
//**********************************************************************************************************************
- public TestDelegateProviderException()
+ public DelegateProviderExceptionTest()
{
super(ObjectProviderException.class);
}
diff --git a/src/test/java/org/apache/commons/proxy/exception/TestInvocationHandlerException.java b/core/src/test/java/org/apache/commons/proxy2/exception/InvocationHandlerExceptionTest.java
similarity index 87%
rename from src/test/java/org/apache/commons/proxy/exception/TestInvocationHandlerException.java
rename to core/src/test/java/org/apache/commons/proxy2/exception/InvocationHandlerExceptionTest.java
index 13ed169..1534b29 100644
--- a/src/test/java/org/apache/commons/proxy/exception/TestInvocationHandlerException.java
+++ b/core/src/test/java/org/apache/commons/proxy2/exception/InvocationHandlerExceptionTest.java
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.exception;
+package org.apache.commons.proxy2.exception;
-public class TestInvocationHandlerException extends AbstractExceptionClassTestCase
+public class InvocationHandlerExceptionTest extends AbstractExceptionClassTestCase
{
//**********************************************************************************************************************
// Constructors
//**********************************************************************************************************************
- public TestInvocationHandlerException()
+ public InvocationHandlerExceptionTest()
{
super(InvokerException.class);
}
diff --git a/src/test/java/org/apache/commons/proxy/exception/TestProxyFactoryException.java b/core/src/test/java/org/apache/commons/proxy2/exception/ProxyFactoryExceptionTest.java
similarity index 88%
rename from src/test/java/org/apache/commons/proxy/exception/TestProxyFactoryException.java
rename to core/src/test/java/org/apache/commons/proxy2/exception/ProxyFactoryExceptionTest.java
index 4498a29..2f56286 100644
--- a/src/test/java/org/apache/commons/proxy/exception/TestProxyFactoryException.java
+++ b/core/src/test/java/org/apache/commons/proxy2/exception/ProxyFactoryExceptionTest.java
@@ -15,19 +15,19 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.exception;
+package org.apache.commons.proxy2.exception;
/**
* @author James Carman
* @since 1.0
*/
-public class TestProxyFactoryException extends AbstractExceptionClassTestCase
+public class ProxyFactoryExceptionTest extends AbstractExceptionClassTestCase
{
//**********************************************************************************************************************
// Constructors
//**********************************************************************************************************************
- public TestProxyFactoryException()
+ public ProxyFactoryExceptionTest()
{
super(ProxyFactoryException.class);
}
diff --git a/core/src/test/java/org/apache/commons/proxy2/impl/MethodSignatureTest.java b/core/src/test/java/org/apache/commons/proxy2/impl/MethodSignatureTest.java
new file mode 100644
index 0000000..a4471ee
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/impl/MethodSignatureTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.impl;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.proxy2.util.AbstractEcho;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.DuplicateEcho;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class MethodSignatureTest extends AbstractTestCase
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ @Test
+ public void testEquals() throws Exception
+ {
+ final MethodSignature sig = new MethodSignature(Echo.class.getMethod("echoBack", String.class));
+ assertTrue(sig.equals(sig));
+ assertFalse(sig.equals("echoBack"));
+ assertEquals(sig, new MethodSignature(Echo.class.getMethod("echoBack", String.class)));
+ assertEquals(sig, new MethodSignature(DuplicateEcho.class.getMethod("echoBack", String.class)));
+ assertFalse(sig.equals(new MethodSignature(Echo.class.getMethod("echoBack", String.class, String.class))));
+ assertFalse(sig.equals(new MethodSignature(Echo.class.getMethod("echo"))));
+ }
+
+ @Test
+ public void testSerialization() throws Exception
+ {
+ final MethodSignature sig = new MethodSignature(Echo.class.getMethod("echoBack", String.class));
+ assertEquals(sig, SerializationUtils.clone(sig));
+ }
+
+ @Test
+ public void testToString() throws Exception
+ {
+ assertEquals("echo()", new MethodSignature(Echo.class.getMethod("echo")).toString());
+ assertEquals("echoBack(Ljava/lang/String;)", new MethodSignature(Echo.class.getMethod("echoBack", String.class)).toString());
+ assertEquals("echoBack([Ljava/lang/String;)", new MethodSignature(Echo.class.getMethod("echoBack", String[].class)).toString());
+ assertEquals("echoBack([[Ljava/lang/String;)", new MethodSignature(Echo.class.getMethod("echoBack", String[][].class)).toString());
+ assertEquals("echoBack([[[Ljava/lang/String;)", new MethodSignature(Echo.class.getMethod("echoBack", String[][][].class)).toString());
+ assertEquals("echoBack(I)", new MethodSignature(Echo.class.getMethod("echoBack", int.class)).toString());
+ assertEquals("echoBack(Z)", new MethodSignature(Echo.class.getMethod("echoBack", boolean.class)).toString());
+ assertEquals("echoBack(Ljava/lang/String;Ljava/lang/String;)", new MethodSignature(Echo.class.getMethod("echoBack", String.class, String.class)).toString());
+ assertEquals("illegalArgument()", new MethodSignature(Echo.class.getMethod("illegalArgument")).toString());
+ assertEquals("ioException()", new MethodSignature(Echo.class.getMethod("ioException")).toString());
+ }
+
+ @Test
+ public void testToMethod() throws Exception
+ {
+ final MethodSignature sig = new MethodSignature(Echo.class.getMethod("echoBack", String.class));
+
+ assertMethodIs(sig.toMethod(Echo.class), Echo.class, "echoBack", String.class);
+ assertMethodIs(sig.toMethod(AbstractEcho.class), AbstractEcho.class, "echoBack", String.class);
+ assertMethodIs(sig.toMethod(EchoImpl.class), AbstractEcho.class, "echoBack", String.class);
+ assertMethodIs(sig.toMethod(DuplicateEcho.class), DuplicateEcho.class, "echoBack", String.class);
+ }
+
+ private void assertMethodIs(Method method, Class<?> declaredBy, String name, Class<?>... parameterTypes)
+ {
+ assertEquals(declaredBy, method.getDeclaringClass());
+ assertEquals(name, method.getName());
+ assertArrayEquals(parameterTypes, method.getParameterTypes());
+ }
+}
\ No newline at end of file
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/InterceptorUtilsTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/InterceptorUtilsTest.java
new file mode 100644
index 0000000..fda9dfb
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/InterceptorUtilsTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.provider.ObjectProviderUtils;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.Echo;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class InterceptorUtilsTest extends AbstractTestCase
+{
+ @Test
+ public void testConstant() throws Throwable
+ {
+ Interceptor interceptor = InterceptorUtils.constant("Hello!");
+ Invocation invocation = mockInvocation(Echo.class, "echoBack", String.class).withArguments("World!").build();
+ assertEquals("Hello!", interceptor.intercept(invocation));
+ }
+
+ @Test
+ public void testProvider() throws Throwable
+ {
+ Interceptor interceptor = InterceptorUtils.provider(ObjectProviderUtils.constant("Foo!"));
+ Invocation invocation = mockInvocation(Echo.class, "echoBack", String.class).withArguments("World!").build();
+ assertEquals("Foo!", interceptor.intercept(invocation));
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testThrowingExceptionObject() throws Throwable
+ {
+ Interceptor interceptor = InterceptorUtils.throwing(new RuntimeException("Oops!"));
+ Invocation invocation = mockInvocation(Echo.class, "echoBack", String.class).withArguments("World!").build();
+ interceptor.intercept(invocation);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testThrowingProvidedException() throws Throwable
+ {
+ Interceptor interceptor = InterceptorUtils.throwing(ObjectProviderUtils.constant(new RuntimeException("Oops!")));
+ Invocation invocation = mockInvocation(Echo.class, "echoBack", String.class).withArguments("World!").build();
+ interceptor.intercept(invocation);
+ }
+
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/InvokerInterceptorTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/InvokerInterceptorTest.java
new file mode 100644
index 0000000..6fea1f0
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/InvokerInterceptorTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.interceptor;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.Echo;
+import org.junit.Test;
+
+public class InvokerInterceptorTest extends AbstractTestCase
+{
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Other Methods
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testIntercept() throws Throwable
+ {
+ final InvokerInterceptor interceptor = new InvokerInterceptor(new Invoker()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable
+ {
+ return "Hello!";
+ }
+ });
+ final Invocation invocation = new MockInvocationBuilder(Echo.class.getDeclaredMethod("echoBack", String.class))
+ .withArguments("foo").build();
+
+ assertEquals("Hello!", interceptor.intercept(invocation));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testWithNullInvoker()
+ {
+ new InvokerInterceptor(null);
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/ObjectProviderInterceptorTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/ObjectProviderInterceptorTest.java
new file mode 100644
index 0000000..09de5e7
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/ObjectProviderInterceptorTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.proxy2.provider.ObjectProviderUtils;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ObjectProviderInterceptorTest extends AbstractTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testIntercept() throws Throwable
+ {
+ ObjectProviderInterceptor interceptor = new ObjectProviderInterceptor(ObjectProviderUtils.constant("Hello!"));
+ assertEquals("Hello!", interceptor.intercept(null));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testWithNullProvider()
+ {
+ new ObjectProviderInterceptor(null);
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/SwitchInterceptorTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/SwitchInterceptorTest.java
new file mode 100644
index 0000000..71c311a
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/SwitchInterceptorTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.interceptor;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.invocation.MethodNameMatcher;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.MockInvocation;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Method;
+
+import static org.apache.commons.proxy2.interceptor.InterceptorUtils.constant;
+
+public class SwitchInterceptorTest extends AbstractTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testWithMultipleAdvices() throws Throwable
+ {
+ SwitchInterceptor interceptor = new SwitchInterceptor();
+ interceptor.when(new MethodNameMatcher("echo")).then(constant("bar"));
+ interceptor.when(new MethodNameMatcher("echoBack")).then(constant("baz"));
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo", "foo");
+ assertEquals("baz", interceptor.intercept(invocation));
+ }
+
+ @Test
+ public void testWithNoAdvice() throws Throwable
+ {
+ SwitchInterceptor interceptor = new SwitchInterceptor();
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo", "foo");
+ assertEquals("foo", interceptor.intercept(invocation));
+ }
+
+ @Test
+ public void testWithSingleAdviceWhichDoesNotMatch() throws Throwable
+ {
+ SwitchInterceptor interceptor = new SwitchInterceptor().when(new MethodNameMatcher("echoBackZZZZ")).then(constant("bar"));
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo", "foo");
+ assertEquals("foo", interceptor.intercept(invocation));
+ }
+
+ @Test
+ public void testWithSingleAdviceWhichMatches() throws Throwable
+ {
+ SwitchInterceptor interceptor = new SwitchInterceptor().when(new MethodNameMatcher("echoBack")).then(constant("bar"));
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo", "foo");
+ assertEquals("bar", interceptor.intercept(invocation));
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/DeclaredByMatcherTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/DeclaredByMatcherTest.java
new file mode 100644
index 0000000..7f1853b
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/DeclaredByMatcherTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.interceptor.matcher;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.invocation.DeclaredByMatcher;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.apache.commons.proxy2.util.MockInvocation;
+import org.junit.Test;
+
+public class DeclaredByMatcherTest extends AbstractTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testExactMatchNonMatching() throws Throwable
+ {
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo");
+ InvocationMatcher matcher = new DeclaredByMatcher(EchoImpl.class, true);
+ assertFalse(matcher.matches(invocation));
+ }
+
+ @Test
+ public void testWithSupertypeMatch() throws Throwable
+ {
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo");
+ InvocationMatcher matcher = new DeclaredByMatcher(EchoImpl.class);
+ assertTrue(matcher.matches(invocation));
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/MethodNameMatcherTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/MethodNameMatcherTest.java
new file mode 100644
index 0000000..e23ce0a
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/MethodNameMatcherTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.interceptor.matcher;
+
+import org.apache.commons.proxy2.interceptor.matcher.invocation.MethodNameMatcher;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.MockInvocation;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+
+import static org.junit.Assert.*;
+
+public class MethodNameMatcherTest extends AbstractTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testWithMatchingMethod() throws Exception
+ {
+ MethodNameMatcher matcher = new MethodNameMatcher("echo");
+ final Method method = Echo.class.getMethod("echo");
+ assertTrue(matcher.matches(new MockInvocation(method,null)));
+ }
+
+ @Test
+ public void testWithNonMatchingMethod() throws Exception
+ {
+ MethodNameMatcher matcher = new MethodNameMatcher("foo");
+ final Method method = Echo.class.getMethod("echo");
+ assertFalse(matcher.matches(new MockInvocation(method, null)));
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/ReturnTypeMatcherTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/ReturnTypeMatcherTest.java
new file mode 100644
index 0000000..8c50ba5
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/ReturnTypeMatcherTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.interceptor.matcher;
+
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.interceptor.matcher.invocation.ReturnTypeMatcher;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.MockInvocation;
+import org.junit.Test;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import static org.junit.Assert.*;
+
+public class ReturnTypeMatcherTest extends AbstractTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testExactMatchNonMatching() throws Throwable
+ {
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo");
+ InvocationMatcher matcher = new ReturnTypeMatcher(Serializable.class, true);
+ assertFalse(matcher.matches(invocation));
+ }
+
+ @Test
+ public void testMatchVoid() throws Throwable
+ {
+ Method method = Echo.class.getMethod("echo");
+ Invocation invocation = new MockInvocation(method, null);
+ InvocationMatcher matcher = new ReturnTypeMatcher(Void.TYPE);
+ assertTrue(matcher.matches(invocation));
+ }
+
+ @Test
+ public void testWithSupertypeMatch() throws Throwable
+ {
+ Method method = Echo.class.getMethod("echoBack", String.class);
+ Invocation invocation = new MockInvocation(method, "foo");
+ InvocationMatcher matcher = new ReturnTypeMatcher(Serializable.class);
+ assertTrue(matcher.matches(invocation));
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/argument/ArgumentMatcherUtilsTest.java b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/argument/ArgumentMatcherUtilsTest.java
new file mode 100644
index 0000000..b261b3a
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/interceptor/matcher/argument/ArgumentMatcherUtilsTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.interceptor.matcher.argument;
+
+import org.apache.commons.proxy2.interceptor.matcher.ArgumentMatcher;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ArgumentMatcherUtilsTest
+{
+ @Test
+ public void testAny() throws Exception
+ {
+ ArgumentMatcher<Object> matcher =ArgumentMatcherUtils.any();
+ assertTrue(matcher.matches(null));
+ assertTrue(matcher.matches("Hello!"));
+ assertTrue(matcher.matches(12345));
+ }
+
+ @Test
+ public void testEq() throws Exception
+ {
+ ArgumentMatcher<String> matcher = ArgumentMatcherUtils.eq("Hello");
+ assertTrue(matcher.matches("Hello"));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testGt() throws Exception
+ {
+ ArgumentMatcher<Integer> matcher = ArgumentMatcherUtils.gt(5);
+ assertTrue(matcher.matches(6));
+ assertFalse(matcher.matches(5));
+ assertFalse(matcher.matches(1));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testGte() throws Exception
+ {
+ ArgumentMatcher<Integer> matcher = ArgumentMatcherUtils.gte(5);
+ assertTrue(matcher.matches(6));
+ assertTrue(matcher.matches(5));
+ assertFalse(matcher.matches(1));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testIsA() throws Exception
+ {
+ ArgumentMatcher<Object> matcher = ArgumentMatcherUtils.isA(String.class);
+ assertFalse(matcher.matches(null));
+ assertTrue(matcher.matches("Hello"));
+ assertFalse(matcher.matches(123));
+ }
+
+ @Test
+ public void testIsNull() throws Exception
+ {
+ ArgumentMatcher<Object> matcher = ArgumentMatcherUtils.isNull();
+ assertTrue(matcher.matches(null));
+ assertFalse(matcher.matches("Hello"));
+ assertFalse(matcher.matches(123));
+ }
+
+ @Test
+ public void testLt() throws Exception
+ {
+ ArgumentMatcher<Integer> matcher = ArgumentMatcherUtils.lt(5);
+ assertTrue(matcher.matches(4));
+ assertFalse(matcher.matches(5));
+ assertFalse(matcher.matches(19));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testLte() throws Exception
+ {
+ ArgumentMatcher<Integer> matcher = ArgumentMatcherUtils.lte(5);
+ assertTrue(matcher.matches(4));
+ assertTrue(matcher.matches(5));
+ assertFalse(matcher.matches(19));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testMatches() throws Exception
+ {
+ ArgumentMatcher<String> matcher = ArgumentMatcherUtils.matches("(abc)+");
+ assertTrue(matcher.matches("abc"));
+ assertTrue(matcher.matches("abcabc"));
+ assertFalse(matcher.matches(""));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testNotNull() throws Exception
+ {
+ ArgumentMatcher<String> matcher = ArgumentMatcherUtils.notNull();
+ assertTrue(matcher.matches("Hello"));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testStartsWith() throws Exception
+ {
+ ArgumentMatcher<String> matcher = ArgumentMatcherUtils.startsWith("abc");
+ assertTrue(matcher.matches("abc"));
+ assertTrue(matcher.matches("abcd"));
+ assertFalse(matcher.matches("ab"));
+ assertFalse(matcher.matches(null));
+ }
+
+ @Test
+ public void testEndsWith() throws Exception
+ {
+ ArgumentMatcher<String> matcher = ArgumentMatcherUtils.endsWith("abc");
+ assertTrue(matcher.matches("abc"));
+ assertTrue(matcher.matches("dabc"));
+ assertFalse(matcher.matches("ab"));
+ assertFalse(matcher.matches(null));
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/invoker/DelegatingInvokerTest.java b/core/src/test/java/org/apache/commons/proxy2/invoker/DelegatingInvokerTest.java
new file mode 100644
index 0000000..d7c585b
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/invoker/DelegatingInvokerTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.invoker;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.provider.ObjectProviderUtils;
+import org.apache.commons.proxy2.util.Echo;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.junit.Test;
+
+public class DelegatingInvokerTest
+{
+
+ @Test
+ public void test() throws Throwable
+ {
+ final Invoker invoker = new DelegatingInvoker<Echo>(ObjectProviderUtils.constant(new EchoImpl()));
+
+ assertEquals("foo",
+ invoker.invoke(null, Echo.class.getDeclaredMethod("echoBack", String.class), new Object[] { "foo" }));
+ }
+
+}
diff --git a/src/test/java/org/apache/commons/proxy/provider/TestBeanProvider.java b/core/src/test/java/org/apache/commons/proxy2/provider/BeanProviderTest.java
similarity index 64%
rename from src/test/java/org/apache/commons/proxy/provider/TestBeanProvider.java
rename to core/src/test/java/org/apache/commons/proxy2/provider/BeanProviderTest.java
index 8973bfa..415c895 100644
--- a/src/test/java/org/apache/commons/proxy/provider/TestBeanProvider.java
+++ b/core/src/test/java/org/apache/commons/proxy2/provider/BeanProviderTest.java
@@ -15,59 +15,42 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.provider;
+package org.apache.commons.proxy2.provider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-import org.apache.commons.proxy.util.AbstractTestCase;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.junit.Test;
-public class TestBeanProvider extends AbstractTestCase
+public class BeanProviderTest extends AbstractTestCase
{
//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************
+ @Test(expected = ObjectProviderException.class)
public void testAbstractBeanClass()
{
- try
- {
- final BeanProvider p = new BeanProvider();
- p.setBeanClass(Number.class);
- p.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
+ final BeanProvider<Number> p = new BeanProvider<Number>(Number.class);
+ p.getObject();
}
+ @Test(expected = ObjectProviderException.class)
public void testNonAccessibleConstructor()
{
- try
- {
- new BeanProvider(MyBean.class).getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
+ new BeanProvider<MyBean>(MyBean.class).getObject();
}
+ @Test
public void testSerialization()
{
- assertSerializable(new BeanProvider(MyBean.class));
+ assertSerializable(new BeanProvider<MyBean>(MyBean.class));
}
+ @Test(expected = NullPointerException.class)
public void testWithNullBeanClass()
{
- try
- {
- final BeanProvider p = new BeanProvider();
- p.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
+ final BeanProvider<Object> p = new BeanProvider<Object>(null);
+ p.getObject();
}
//**********************************************************************************************************************
diff --git a/src/test/java/org/apache/commons/proxy/provider/TestCloningProvider.java b/core/src/test/java/org/apache/commons/proxy2/provider/CloningProviderTest.java
similarity index 65%
rename from src/test/java/org/apache/commons/proxy/provider/TestCloningProvider.java
rename to core/src/test/java/org/apache/commons/proxy2/provider/CloningProviderTest.java
index adac321..c332f49 100644
--- a/src/test/java/org/apache/commons/proxy/provider/TestCloningProvider.java
+++ b/core/src/test/java/org/apache/commons/proxy2/provider/CloningProviderTest.java
@@ -15,74 +15,67 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.provider;
+package org.apache.commons.proxy2.provider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-import org.apache.commons.proxy.util.AbstractTestCase;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.junit.Test;
import java.util.Date;
-public class TestCloningProvider extends AbstractTestCase
+import static org.junit.Assert.*;
+
+public class CloningProviderTest extends AbstractTestCase
{
//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************
+ @Test
public void testSerialization()
{
- assertSerializable(new CloningProvider(new Date()));
+ assertSerializable(new CloningProvider<Date>(new Date()));
}
+ @Test
public void testValidCloneable()
{
final Date now = new Date();
- final CloningProvider provider = new CloningProvider(now);
- final Date clone1 = ( Date ) provider.getObject();
+ final CloningProvider<Date> provider = new CloningProvider<Date>(now);
+ final Date clone1 = (Date) provider.getObject();
assertEquals(now, clone1);
assertNotSame(now, clone1);
- final Date clone2 = ( Date ) provider.getObject();
+ final Date clone2 = (Date) provider.getObject();
assertEquals(now, clone2);
assertNotSame(now, clone2);
assertNotSame(clone2, clone1);
}
+ @Test
public void testWithExceptionThrown()
{
- final CloningProvider provider = new CloningProvider(new ExceptionCloneable());
+ final CloningProvider<ExceptionCloneable> provider = new CloningProvider<ExceptionCloneable>(new ExceptionCloneable());
try
{
provider.getObject();
fail();
}
- catch( ObjectProviderException e )
+ catch (ObjectProviderException e)
{
}
}
+ @Test(expected = IllegalArgumentException.class)
public void testWithInvalidCloneable()
{
- final CloningProvider provider = new CloningProvider(new InvalidCloneable());
- try
- {
- provider.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
+ new CloningProvider<InvalidCloneable>(new InvalidCloneable());
}
- public void testWithPrivateCloneMethod()
+ @Test(expected = IllegalArgumentException.class)
+ public void testWithProtectedCloneMethod()
{
- final CloningProvider provider = new CloningProvider(new PrivateCloneable());
- try
- {
- provider.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
+ final CloningProvider<ProtectedCloneable> provider = new CloningProvider<ProtectedCloneable>(new ProtectedCloneable());
+ provider.getObject();
}
//**********************************************************************************************************************
@@ -101,7 +94,7 @@
{
}
- public static class PrivateCloneable implements Cloneable
+ public static class ProtectedCloneable implements Cloneable
{
protected Object clone()
{
diff --git a/src/test/java/org/apache/commons/proxy/provider/TestConstantProvider.java b/core/src/test/java/org/apache/commons/proxy2/provider/ConstantProviderTest.java
similarity index 75%
rename from src/test/java/org/apache/commons/proxy/provider/TestConstantProvider.java
rename to core/src/test/java/org/apache/commons/proxy2/provider/ConstantProviderTest.java
index 8c4eee3..6c756e7 100644
--- a/src/test/java/org/apache/commons/proxy/provider/TestConstantProvider.java
+++ b/core/src/test/java/org/apache/commons/proxy2/provider/ConstantProviderTest.java
@@ -15,28 +15,33 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.provider;
+package org.apache.commons.proxy2.provider;
-import org.apache.commons.proxy.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
/**
* @since 1.0
*/
-public class TestConstantProvider extends AbstractTestCase
+public class ConstantProviderTest extends AbstractTestCase
{
//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************
+ @Test
public void testGetObject() throws Exception
{
final String s = "Hello, World!";
- final ConstantProvider provider = new ConstantProvider(s);
+ final ConstantProvider<String> provider = new ConstantProvider<String>(s);
assertSame(s, provider.getObject());
}
+ @Test
public void testSerialization()
{
- assertSerializable(new ConstantProvider("Hello, World!"));
+ assertSerializable(new ConstantProvider<String>("Hello, World!"));
}
}
diff --git a/src/test/java/org/apache/commons/proxy/provider/CountingProvider.java b/core/src/test/java/org/apache/commons/proxy2/provider/CountingProvider.java
similarity index 88%
rename from src/test/java/org/apache/commons/proxy/provider/CountingProvider.java
rename to core/src/test/java/org/apache/commons/proxy2/provider/CountingProvider.java
index ae4d3e6..18d46a2 100644
--- a/src/test/java/org/apache/commons/proxy/provider/CountingProvider.java
+++ b/core/src/test/java/org/apache/commons/proxy2/provider/CountingProvider.java
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.provider;
+package org.apache.commons.proxy2.provider;
-import org.apache.commons.proxy.ObjectProvider;
+import org.apache.commons.proxy2.ObjectProvider;
/**
* @author James Carman
* @since 1.0
*/
-public class CountingProvider extends ProviderDecorator
+public class CountingProvider<T> extends ProviderDecorator<T>
{
//**********************************************************************************************************************
// Fields
@@ -35,7 +35,7 @@
// Constructors
//**********************************************************************************************************************
- public CountingProvider( ObjectProvider inner )
+ public CountingProvider( ObjectProvider<? extends T> inner )
{
super(inner);
}
@@ -45,7 +45,7 @@
//**********************************************************************************************************************
- public synchronized Object getObject()
+ public synchronized T getObject()
{
count++;
return super.getObject();
diff --git a/src/test/java/org/apache/commons/proxy/provider/TestNullProvider.java b/core/src/test/java/org/apache/commons/proxy2/provider/NullProviderTest.java
similarity index 76%
rename from src/test/java/org/apache/commons/proxy/provider/TestNullProvider.java
rename to core/src/test/java/org/apache/commons/proxy2/provider/NullProviderTest.java
index 12f59f5..fbf8b04 100644
--- a/src/test/java/org/apache/commons/proxy/provider/TestNullProvider.java
+++ b/core/src/test/java/org/apache/commons/proxy2/provider/NullProviderTest.java
@@ -15,28 +15,33 @@
* limitations under the License.
*/
-package org.apache.commons.proxy.provider;
+package org.apache.commons.proxy2.provider;
-import org.apache.commons.proxy.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
/**
* @author James Carman
* @since 1.0
*/
-public class TestNullProvider extends AbstractTestCase
+public class NullProviderTest extends AbstractTestCase
{
//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************
+ @Test
public void testGetObject()
{
- final NullProvider provider = new NullProvider();
+ final NullProvider<Object> provider = new NullProvider<Object>();
assertNull(provider.getObject());
}
+ @Test
public void testSerialization()
{
- assertSerializable(new NullProvider());
+ assertSerializable(new NullProvider<Object>());
}
}
diff --git a/core/src/test/java/org/apache/commons/proxy2/provider/ObjectProviderUtilsTest.java b/core/src/test/java/org/apache/commons/proxy2/provider/ObjectProviderUtilsTest.java
new file mode 100644
index 0000000..89ce98a
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/provider/ObjectProviderUtilsTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.provider;
+
+import org.apache.commons.proxy2.util.AbstractTestCase;
+import org.apache.commons.proxy2.util.EchoImpl;
+import org.junit.Test;
+
+import java.util.Date;
+
+import static org.junit.Assert.*;
+
+public class ObjectProviderUtilsTest extends AbstractTestCase
+{
+ @Test
+ public void testBean() throws Exception
+ {
+ assertTrue(ObjectProviderUtils.bean(EchoImpl.class) instanceof BeanProvider);
+ }
+
+ @Test
+ public void testCloning() throws Exception
+ {
+ assertTrue(ObjectProviderUtils.cloning(new Date()) instanceof CloningProvider);
+ }
+
+ @Test
+ public void testConstant() throws Exception
+ {
+ assertTrue(ObjectProviderUtils.constant("Hello") instanceof ConstantProvider);
+ }
+
+ @Test
+ public void testNullValue() throws Exception
+ {
+ assertTrue(ObjectProviderUtils.nullValue() instanceof NullProvider);
+ }
+
+ @Test
+ public void testSingleton() throws Exception
+ {
+ assertTrue(ObjectProviderUtils.singleton(new ConstantProvider<Object>("Hello")) instanceof SingletonProvider);
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/AbstractEcho.java b/core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java
similarity index 94%
rename from src/test/java/org/apache/commons/proxy/util/AbstractEcho.java
rename to core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java
index 68459b0..fe8bc51 100644
--- a/src/test/java/org/apache/commons/proxy/util/AbstractEcho.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/AbstractEcho.java
@@ -1,36 +1,37 @@
-/*
- * 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.proxy.util;
-
-import java.io.Serializable;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public abstract class AbstractEcho implements Echo, Serializable
-{
-//**********************************************************************************************************************
-// Echo Implementation
-//**********************************************************************************************************************
-
- public String echoBack( String message )
- {
- return message;
- }
-}
+/*
+ * 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.util;
+
+import java.io.Serializable;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractEcho implements Echo, Serializable
+{
+//**********************************************************************************************************************
+// Echo Implementation
+//**********************************************************************************************************************
+
+ public String echoBack( String message )
+ {
+ return message;
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java b/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java
new file mode 100644
index 0000000..78fb664
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/util/AbstractTestCase.java
@@ -0,0 +1,71 @@
+package org.apache.commons.proxy2.util;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.builder.Builder;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.ProxyUtils;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author James Carman
+ * @since 1.1
+ */
+public abstract class AbstractTestCase
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ protected void assertSerializable( Object o )
+ {
+ assertTrue(o instanceof Serializable);
+ SerializationUtils.clone(( Serializable ) o);
+ }
+
+ protected MockInvocationBuilder mockInvocation(Class<?> type, String name, Class<?>... argumentTypes)
+ {
+ try
+ {
+ return new MockInvocationBuilder(Validate.notNull(type).getMethod(name, argumentTypes));
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new IllegalArgumentException("Method not found.", e);
+ }
+ }
+
+ protected static final class MockInvocationBuilder implements Builder<Invocation>
+ {
+ private final Method method;
+ private Object[] arguments = ProxyUtils.EMPTY_ARGUMENTS;
+ private Object returnValue = null;
+
+ public MockInvocationBuilder(Method method)
+ {
+ this.method = method;
+ }
+
+ public MockInvocationBuilder withArguments(Object... arguments)
+ {
+ this.arguments = arguments;
+ return this;
+ }
+
+ public MockInvocationBuilder returning(Object value)
+ {
+ this.returnValue = value;
+ return this;
+ }
+
+ @Override
+ public Invocation build()
+ {
+ return new MockInvocation(method, returnValue, arguments);
+ }
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java b/core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java
similarity index 96%
rename from src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
rename to core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java
index f73551d..cc64d97 100644
--- a/src/test/java/org/apache/commons/proxy/util/DuplicateEcho.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/DuplicateEcho.java
@@ -1,31 +1,31 @@
-/*
- * 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.proxy.util;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface DuplicateEcho
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public String echoBack( String message );
-}
+/*
+ * 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.util;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+public interface DuplicateEcho
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ public String echoBack( String message );
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/Echo.java b/core/src/test/java/org/apache/commons/proxy2/util/Echo.java
similarity index 90%
rename from src/test/java/org/apache/commons/proxy/util/Echo.java
rename to core/src/test/java/org/apache/commons/proxy2/util/Echo.java
index 549fe29..af04e06 100644
--- a/src/test/java/org/apache/commons/proxy/util/Echo.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/Echo.java
@@ -1,47 +1,52 @@
-/*
- * 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.proxy.util;
-
-import java.io.IOException;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface Echo
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void echo();
-
- public String echoBack( String message );
-
- public String echoBack( String[] messages );
-
- public int echoBack( int i );
-
- public boolean echoBack( boolean b );
-
- public String echoBack( String message1, String message2 );
-
- public void illegalArgument();
-
- public void ioException() throws IOException;
-}
+/*
+ * 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.util;
+
+import java.io.IOException;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+public interface Echo
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ public void echo();
+
+ public String echoBack( String message );
+
+ public String echoBack( String[] messages );
+
+ public String echoBack( String[][] messages );
+
+ public String echoBack( String[][][] messages );
+
+ public int echoBack( int i );
+
+ public boolean echoBack( boolean b );
+
+ public String echoBack( String message1, String message2 );
+
+ public void illegalArgument();
+
+ public void ioException() throws IOException;
+
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/EchoImpl.java b/core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java
similarity index 78%
rename from src/test/java/org/apache/commons/proxy/util/EchoImpl.java
rename to core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java
index 10cd019..66169d5 100644
--- a/src/test/java/org/apache/commons/proxy/util/EchoImpl.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/EchoImpl.java
@@ -1,79 +1,99 @@
-/*
- * 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.proxy.util;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class EchoImpl extends AbstractEcho implements DuplicateEcho, Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static final long serialVersionUID = -4844873352607521103L;
-
-//**********************************************************************************************************************
-// Echo Implementation
-//**********************************************************************************************************************
-
-
- public void echo()
- {
- }
-
- public boolean echoBack( boolean b )
- {
- return b;
- }
-
- public String echoBack( String[] messages )
- {
- final StringBuffer sb = new StringBuffer();
- for( int i = 0; i < messages.length; i++ )
- {
- String message = messages[i];
- sb.append(message);
- }
- return sb.toString();
- }
-
- public int echoBack( int i )
- {
- return i;
- }
-
- public String echoBack( String message1, String message2 )
- {
- return message1 + message2;
- }
-
- public void illegalArgument()
- {
- throw new IllegalArgumentException("dummy message");
- }
-
- public void ioException() throws IOException
- {
- throw new IOException("dummy message");
- }
-}
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+public class EchoImpl extends AbstractEcho implements DuplicateEcho, Serializable
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private static final long serialVersionUID = -4844873352607521103L;
+
+//**********************************************************************************************************************
+// Echo Implementation
+//**********************************************************************************************************************
+
+
+ public void echo()
+ {
+ }
+
+ public boolean echoBack( boolean b )
+ {
+ return b;
+ }
+
+ public String echoBack( String[] messages )
+ {
+ final StringBuilder sb = new StringBuilder();
+ for( int i = 0; i < messages.length; i++ )
+ {
+ String message = messages[i];
+ sb.append(message);
+ }
+ return sb.toString();
+ }
+
+ public String echoBack( String[][] messages )
+ {
+ final StringBuilder sb = new StringBuilder();
+ for( int i = 0; i < messages.length; i++ )
+ {
+ sb.append(echoBack(messages[i]));
+ }
+ return sb.toString();
+ }
+
+ public String echoBack( String[][][] messages )
+ {
+ final StringBuilder sb = new StringBuilder();
+ for( int i = 0; i < messages.length; i++ )
+ {
+ sb.append(echoBack(messages[i]));
+ }
+ return sb.toString();
+ }
+
+ public int echoBack( int i )
+ {
+ return i;
+ }
+
+ public String echoBack( String message1, String message2 )
+ {
+ return message1 + message2;
+ }
+
+ public void illegalArgument()
+ {
+ throw new IllegalArgumentException("dummy message");
+ }
+
+ public void ioException() throws IOException
+ {
+ throw new IOException("dummy message");
+ }
+}
diff --git a/core/src/test/java/org/apache/commons/proxy2/util/MockInvocation.java b/core/src/test/java/org/apache/commons/proxy2/util/MockInvocation.java
new file mode 100644
index 0000000..92c74e5
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/proxy2/util/MockInvocation.java
@@ -0,0 +1,56 @@
+package org.apache.commons.proxy2.util;
+
+import org.apache.commons.proxy2.Invocation;
+
+import java.lang.reflect.Method;
+
+public class MockInvocation implements Invocation
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final Method method;
+ private final Object[] arguments;
+ private final Object returnValue;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public MockInvocation(Method method, Object returnValue, Object... arguments)
+ {
+ this.returnValue = returnValue;
+ this.arguments = arguments;
+ this.method = method;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Invocation Implementation
+//----------------------------------------------------------------------------------------------------------------------
+
+
+ @Override
+ public Object[] getArguments()
+ {
+ return arguments;
+ }
+
+ @Override
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ @Override
+ public Object getProxy()
+ {
+ return null;
+ }
+
+ @Override
+ public Object proceed() throws Throwable
+ {
+ return returnValue;
+ }
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/QuoteService.java b/core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java
similarity index 96%
rename from src/test/java/org/apache/commons/proxy/util/QuoteService.java
rename to core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java
index 82c37d7..bd8d841 100644
--- a/src/test/java/org/apache/commons/proxy/util/QuoteService.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/QuoteService.java
@@ -1,34 +1,34 @@
-/*
- * 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.proxy.util;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public interface QuoteService extends Remote
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public float getQuote( String symbol ) throws RemoteException;
-}
+/*
+ * 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.util;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+public interface QuoteService extends Remote
+{
+//**********************************************************************************************************************
+// Other Methods
+//**********************************************************************************************************************
+
+ public float getQuote( String symbol ) throws RemoteException;
+}
diff --git a/src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java b/core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java
similarity index 85%
rename from src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java
rename to core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java
index c98a6de..466925e 100644
--- a/src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java
+++ b/core/src/test/java/org/apache/commons/proxy2/util/SuffixInterceptor.java
@@ -1,53 +1,59 @@
-/*
- * 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.proxy.util;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class SuffixInterceptor implements Interceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final String suffix;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public SuffixInterceptor( String suffix )
- {
- this.suffix = suffix;
- }
-
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
-
- public Object intercept( Invocation methodInvocation ) throws Throwable
- {
- return methodInvocation.proceed() + suffix;
- }
-}
+/*
+ * 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.util;
+
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invocation;
+
+/**
+ * @author James Carman
+ * @since 1.0
+ */
+@SuppressWarnings("serial")
+public class SuffixInterceptor implements Interceptor
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private final String suffix;
+
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ public SuffixInterceptor( String suffix )
+ {
+ this.suffix = suffix;
+ }
+
+//**********************************************************************************************************************
+// Interceptor Implementation
+//**********************************************************************************************************************
+
+
+ public Object intercept( Invocation methodInvocation ) throws Throwable
+ {
+ Object result = methodInvocation.proceed();
+ if (result instanceof String)
+ {
+ result = ((String) result) + suffix;
+ }
+ return result;
+ }
+}
diff --git a/src/test/resources/log4j.properties b/core/src/test/resources/log4j.properties
similarity index 99%
rename from src/test/resources/log4j.properties
rename to core/src/test/resources/log4j.properties
index b981287..1a98c66 100644
--- a/src/test/resources/log4j.properties
+++ b/core/src/test/resources/log4j.properties
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+
log4j.rootLogger=DEBUG, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
diff --git a/doap_proxy.rdf b/doap_proxy.rdf
deleted file mode 100644
index 095c057..0000000
--- a/doap_proxy.rdf
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0"?>
-<rdf:RDF xmlns="http://usefulinc.com/ns/doap#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:asfext="http://projects.apache.org/ns/asfext#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:doap="http://usefulinc.com/ns/doap#" xml:lang="en">
- <Project rdf:about="http://commons.apache.org/proxy/">
- <name>Apache Commons Proxy</name>
- <homepage rdf:resource="http://commons.apache.org/proxy/"/>
- <programming-language>Java</programming-language>
- <category rdf:resource="http://projects.apache.org/category/library"/>
- <license rdf:resource="http://usefulinc.com/doap/licenses/asl20"/>
- <bug-database rdf:resource="http://issues.apache.org/jira/browse/POOL"/>
- <download-page rdf:resource="http://commons.apache.org/proxy/download_proxy.cgi"/>
- <asfext:pmc rdf:resource="http://commons.apache.org/"/>
- <shortdesc xml:lang="en">Commons Dynamic Proxy Library</shortdesc>
- <description xml:lang="en">Commons Dynamic Proxy Library</description>
- <repository>
- <SVNRepository>
- <browse rdf:resource="http://svn.apache.org/repos/asf/commons/proper/proxy/trunk"/>
- <location rdf:resource="http://svn.apache.org/repos/asf/commons/proper/proxy"/>
- </SVNRepository>
- </repository>
- <release>
- <Version>
- <name>commons-proxy</name>
- <created>2008-02-28</created>
- <revision>1.0</revision>
- </Version>
- </release>
- <mailing-list rdf:resource="http://commons.apache.org/mail-lists.html"/>
- </Project>
-</rdf:RDF>
diff --git a/javassist/pom.xml b/javassist/pom.xml
new file mode 100644
index 0000000..3782009
--- /dev/null
+++ b/javassist/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy2-javassist</artifactId>
+ <name>Commons Proxy Javassist Proxies Module</name>
+ <description>Proxies based on classes dynamically generated using Javassist
+ </description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>javassist</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/main/java/org/apache/commons/proxy/factory/javassist/JavassistInvocation.java b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java
similarity index 74%
rename from src/main/java/org/apache/commons/proxy/factory/javassist/JavassistInvocation.java
rename to javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java
index 5a2e8ae..0bf9a30 100644
--- a/src/main/java/org/apache/commons/proxy/factory/javassist/JavassistInvocation.java
+++ b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistInvocation.java
@@ -1,223 +1,237 @@
-/*
- * 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.proxy.factory.javassist;
-
-import javassist.CannotCompileException;
-import javassist.CtClass;
-import javassist.CtConstructor;
-import javassist.CtMethod;
-import org.apache.commons.proxy.Invocation;
-import org.apache.commons.proxy.ProxyUtils;
-
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * A <a href="http://www.jboss.org/products/javassist">Javassist</a>-based {@link Invocation} implementation. This
- * class actually serves as the superclass for all <a href="http://www.jboss.org/products/javassist">Javassist</a>-based
- * method invocations. Subclasses are dynamically created to deal with specific interface methods (they're hard-wired).
- *
- * @author James Carman
- * @since 1.0
- */
-public abstract class JavassistInvocation implements Invocation
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static WeakHashMap loaderToClassCache = new WeakHashMap();
- protected final Method method;
- protected final Object target;
- protected final Object[] arguments;
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- private static String createCastExpression( Class type, String objectToCast )
- {
- if( !type.isPrimitive() )
- {
- return "( " + ProxyUtils.getJavaClassName(type) + " )" + objectToCast;
- }
- else
- {
- return "( ( " + ProxyUtils.getWrapperClass(type).getName() + " )" + objectToCast + " )." +
- type.getName() + "Value()";
- }
- }
-
- private static Class createInvocationClass( ClassLoader classLoader, Method interfaceMethod )
- throws CannotCompileException
- {
- Class invocationClass;
- final CtClass ctClass = JavassistUtils.createClass(
- getSimpleName(interfaceMethod.getDeclaringClass()) + "_" + interfaceMethod.getName() +
- "_invocation",
- JavassistInvocation.class);
- final CtConstructor constructor = new CtConstructor(
- JavassistUtils.resolve(new Class[] {Method.class, Object.class, Object[].class}),
- ctClass);
- constructor.setBody("{\n\tsuper($$);\n}");
- ctClass.addConstructor(constructor);
- final CtMethod proceedMethod = new CtMethod(JavassistUtils.resolve(Object.class), "proceed",
- JavassistUtils.resolve(new Class[0]), ctClass);
- final Class[] argumentTypes = interfaceMethod.getParameterTypes();
- final StringBuffer proceedBody = new StringBuffer("{\n");
- if( !Void.TYPE.equals(interfaceMethod.getReturnType()) )
- {
- proceedBody.append("\treturn ");
- if( interfaceMethod.getReturnType().isPrimitive() )
- {
- proceedBody.append("new ");
- proceedBody.append(ProxyUtils.getWrapperClass(interfaceMethod.getReturnType()).getName());
- proceedBody.append("( ");
- }
- }
- else
- {
- proceedBody.append("\t");
- }
- proceedBody.append("( (");
- proceedBody.append(ProxyUtils.getJavaClassName(interfaceMethod.getDeclaringClass()));
- proceedBody.append(" )target ).");
- proceedBody.append(interfaceMethod.getName());
- proceedBody.append("(");
- for( int i = 0; i < argumentTypes.length; ++i )
- {
- final Class argumentType = argumentTypes[i];
- proceedBody.append(createCastExpression(argumentType, "arguments[" + i + "]"));
- if( i != argumentTypes.length - 1 )
- {
- proceedBody.append(", ");
- }
- }
- if( !Void.TYPE.equals(interfaceMethod.getReturnType()) && interfaceMethod.getReturnType().isPrimitive() )
- {
- proceedBody.append(") );\n");
- }
- else
- {
- proceedBody.append(");\n");
- }
- if( Void.TYPE.equals(interfaceMethod.getReturnType()) )
- {
- proceedBody.append("\treturn null;\n");
- }
- proceedBody.append("}");
- final String body = proceedBody.toString();
- proceedMethod.setBody(body);
- ctClass.addMethod(proceedMethod);
- invocationClass = ctClass.toClass(classLoader);
- return invocationClass;
- }
-
- private static Map getClassCache( ClassLoader classLoader )
- {
- Map cache = ( Map ) loaderToClassCache.get(classLoader);
- if( cache == null )
- {
- cache = new HashMap();
- loaderToClassCache.put(classLoader, cache);
- }
- return cache;
- }
-
- /**
- * Returns a method invocation class specifically coded to invoke the supplied interface method.
- *
- * @param classLoader the classloader to use
- * @param interfaceMethod the interface method
- * @return a method invocation class specifically coded to invoke the supplied interface method
- * @throws CannotCompileException if a compilation error occurs
- */
- synchronized static Class getMethodInvocationClass( ClassLoader classLoader,
- Method interfaceMethod )
- throws CannotCompileException
- {
- final Map classCache = getClassCache(classLoader);
- final String key = toClassCacheKey(interfaceMethod);
- final WeakReference invocationClassRef = ( WeakReference ) classCache.get(key);
- Class invocationClass;
- if( invocationClassRef == null )
- {
- invocationClass = createInvocationClass(classLoader, interfaceMethod);
- classCache.put(key, new WeakReference(invocationClass));
- }
- else
- {
- synchronized( invocationClassRef )
- {
- invocationClass = ( Class ) invocationClassRef.get();
- if( invocationClass == null )
- {
- invocationClass = createInvocationClass(classLoader, interfaceMethod);
- classCache.put(key, new WeakReference(invocationClass));
- }
- }
- }
- return invocationClass;
- }
-
- private static String getSimpleName( Class c )
- {
- final String name = c.getName();
- final int ndx = name.lastIndexOf('.');
- return ndx == -1 ? name : name.substring(ndx + 1);
- }
-
- private static String toClassCacheKey( Method method )
- {
- return String.valueOf(method);
- }
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public JavassistInvocation( Method method, Object target, Object[] arguments )
- {
- this.method = method;
- this.target = target;
- this.arguments = arguments;
- }
-
-//**********************************************************************************************************************
-// Invocation Implementation
-//**********************************************************************************************************************
-
- public Object[] getArguments()
- {
- return arguments;
- }
-
- public Method getMethod()
- {
- return method;
- }
-
- public Object getProxy()
- {
- return target;
- }
-}
-
+/*
+ * 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.javassist;
+
+import javassist.CannotCompileException;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.proxy2.Invocation;
+import org.apache.commons.proxy2.ProxyUtils;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <a href="http://www.jboss.org/products/javassist">Javassist</a>-based {@link Invocation} implementation. This
+ * class actually serves as the superclass for all <a href="http://www.jboss.org/products/javassist">Javassist</a>-based
+ * method invocations. Subclasses are dynamically created to deal with specific interface methods (they're hard-wired).
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+public abstract class JavassistInvocation implements Invocation
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private static WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderToClassCache = new WeakHashMap<ClassLoader, Map<String,WeakReference<Class<?>>>>();
+
+ /** The proxy object */
+ private final Object proxy;
+
+ /** The target object */
+ private final Object target;
+
+ /** The invoked method */
+ private final Method method;
+
+ /** The method arguments */
+ private final Object[] arguments;
+
+//**********************************************************************************************************************
+// Static Methods
+//**********************************************************************************************************************
+
+ private static String createCastExpression( Class<?> type, String objectToCast )
+ {
+ if( !type.isPrimitive() )
+ {
+ return "( " + ProxyUtils.getJavaClassName(type) + " )" + objectToCast;
+ }
+ else
+ {
+ return "( ( " + ProxyUtils.getWrapperClass(type).getName() + " )" + objectToCast + " )." +
+ type.getName() + "Value()";
+ }
+ }
+
+ private static Class<?> createInvocationClass( ClassLoader classLoader, Method interfaceMethod )
+ throws CannotCompileException
+ {
+ Class<?> invocationClass;
+ final CtClass ctClass = JavassistUtils.createClass(
+ getSimpleName(interfaceMethod.getDeclaringClass()) + "_" + interfaceMethod.getName() +
+ "_invocation",
+ JavassistInvocation.class);
+ final CtConstructor constructor = new CtConstructor(
+ JavassistUtils.resolve(new Class[] { Object.class, Object.class, Method.class, Object[].class }),
+ ctClass);
+ constructor.setBody("{\n\tsuper($$);\n}");
+ ctClass.addConstructor(constructor);
+ final CtMethod proceedMethod = new CtMethod(JavassistUtils.resolve(Object.class), "proceed",
+ JavassistUtils.resolve(new Class[0]), ctClass);
+ final Class<?>[] argumentTypes = interfaceMethod.getParameterTypes();
+ final StringBuilder proceedBody = new StringBuilder("{\n");
+ if( !Void.TYPE.equals(interfaceMethod.getReturnType()) )
+ {
+ proceedBody.append("\treturn ");
+ if( interfaceMethod.getReturnType().isPrimitive() )
+ {
+ proceedBody.append("new ");
+ proceedBody.append(ProxyUtils.getWrapperClass(interfaceMethod.getReturnType()).getName());
+ proceedBody.append("( ");
+ }
+ }
+ else
+ {
+ proceedBody.append("\t");
+ }
+ proceedBody.append("( (");
+ proceedBody.append(ProxyUtils.getJavaClassName(interfaceMethod.getDeclaringClass()));
+ proceedBody.append(" )getTarget() ).");
+ proceedBody.append(interfaceMethod.getName());
+ proceedBody.append("(");
+ for( int i = 0; i < argumentTypes.length; ++i )
+ {
+ final Class<?> argumentType = argumentTypes[i];
+ proceedBody.append(createCastExpression(argumentType, "getArguments()[" + i + "]"));
+ if( i != argumentTypes.length - 1 )
+ {
+ proceedBody.append(", ");
+ }
+ }
+ if( !Void.TYPE.equals(interfaceMethod.getReturnType()) && interfaceMethod.getReturnType().isPrimitive() )
+ {
+ proceedBody.append(") );\n");
+ }
+ else
+ {
+ proceedBody.append(");\n");
+ }
+ if( Void.TYPE.equals(interfaceMethod.getReturnType()) )
+ {
+ proceedBody.append("\treturn null;\n");
+ }
+ proceedBody.append("}");
+ final String body = proceedBody.toString();
+ proceedMethod.setBody(body);
+ ctClass.addMethod(proceedMethod);
+ invocationClass = ctClass.toClass(classLoader);
+ return invocationClass;
+ }
+
+ private static Map<String, WeakReference<Class<?>>> getClassCache( ClassLoader classLoader )
+ {
+ Map<String, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);
+ if( cache == null )
+ {
+ cache = new HashMap<String, WeakReference<Class<?>>>();
+ loaderToClassCache.put(classLoader, cache);
+ }
+ return cache;
+ }
+
+ /**
+ * Returns a method invocation class specifically coded to invoke the supplied interface method.
+ *
+ * @param classLoader the classloader to use
+ * @param interfaceMethod the interface method
+ * @return a method invocation class specifically coded to invoke the supplied interface method
+ * @throws CannotCompileException if a compilation error occurs
+ */
+ static synchronized Class<?> getMethodInvocationClass( ClassLoader classLoader,
+ Method interfaceMethod )
+ throws CannotCompileException
+ {
+ final Map<String, WeakReference<Class<?>>> classCache = getClassCache(classLoader);
+ final String key = toClassCacheKey(interfaceMethod);
+ final WeakReference<Class<?>> invocationClassRef = classCache.get(key);
+ Class<?> invocationClass;
+ if( invocationClassRef == null )
+ {
+ invocationClass = createInvocationClass(classLoader, interfaceMethod);
+ classCache.put(key, new WeakReference<Class<?>>(invocationClass));
+ }
+ else
+ {
+ synchronized( invocationClassRef )
+ {
+ invocationClass = invocationClassRef.get();
+ if( invocationClass == null )
+ {
+ invocationClass = createInvocationClass(classLoader, interfaceMethod);
+ classCache.put(key, new WeakReference<Class<?>>(invocationClass));
+ }
+ }
+ }
+ return invocationClass;
+ }
+
+ private static String getSimpleName( Class<?> c )
+ {
+ final String name = c.getName();
+ final int ndx = name.lastIndexOf('.');
+ return ndx == -1 ? name : name.substring(ndx + 1);
+ }
+
+ private static String toClassCacheKey( Method method )
+ {
+ return String.valueOf(method);
+ }
+
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ protected JavassistInvocation( Object proxy, Object target, Method method, Object[] arguments )
+ {
+ this.proxy = proxy;
+ this.target = target;
+ this.method = method;
+ this.arguments = ArrayUtils.clone(arguments);
+ }
+
+//**********************************************************************************************************************
+// Invocation Implementation
+//**********************************************************************************************************************
+ protected final Object getTarget()
+ {
+ return target;
+ }
+
+ public Object[] getArguments()
+ {
+ return arguments;
+ }
+
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public Object getProxy()
+ {
+ return proxy;
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java
similarity index 73%
rename from src/main/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java
rename to javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java
index 7a532f2..4ba823e 100644
--- a/src/main/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java
+++ b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistProxyFactory.java
@@ -1,282 +1,285 @@
-/*
- * 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.proxy.factory.javassist;
-
-import javassist.CannotCompileException;
-import javassist.CtClass;
-import javassist.CtConstructor;
-import javassist.CtMethod;
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.exception.ProxyFactoryException;
-import org.apache.commons.proxy.factory.util.AbstractProxyClassGenerator;
-import org.apache.commons.proxy.factory.util.AbstractSubclassingProxyFactory;
-import org.apache.commons.proxy.factory.util.ProxyClassCache;
-
-import java.lang.reflect.Method;
-
-/**
- * A <a href="http://www.jboss.org/products/javassist">Javassist</a>-based {@link org.apache.commons.proxy.ProxyFactory}
- * implementation.
- * <p/>
- * <b>Dependencies</b>: <ul> <li>Javassist version 3.0 or greater</li> </ul> </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class JavassistProxyFactory extends AbstractSubclassingProxyFactory
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static final String GET_METHOD_METHOD_NAME = "_javassistGetMethod";
-
- private static final ProxyClassCache delegatingProxyClassCache = new ProxyClassCache(
- new DelegatingProxyClassGenerator());
- private static final ProxyClassCache interceptorProxyClassCache = new ProxyClassCache(
- new InterceptorProxyClassGenerator());
- private static final ProxyClassCache invocationHandlerProxyClassCache = new ProxyClassCache(
- new InvokerProxyClassGenerator());
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- private static void addGetMethodMethod(CtClass proxyClass) throws CannotCompileException
- {
- final CtMethod method = new CtMethod(JavassistUtils.resolve(Method.class), GET_METHOD_METHOD_NAME,
- JavassistUtils.resolve(new Class[]{String.class, String.class, Class[].class}), proxyClass);
- final String body = "try { return Class.forName($1).getMethod($2, $3); } catch( Exception e ) " +
- "{ throw new RuntimeException(\"Unable to look up method.\", e); }";
- method.setBody(body);
- proxyClass.addMethod(method);
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public Object createDelegatorProxy(ClassLoader classLoader, ObjectProvider targetProvider,
- Class[] proxyClasses)
- {
- try
- {
- final Class clazz = delegatingProxyClassCache.getProxyClass(classLoader, proxyClasses);
- return clazz.getConstructor(new Class[]{ObjectProvider.class})
- .newInstance(new Object[]{targetProvider});
- }
- catch (Exception e)
- {
- throw new ProxyFactoryException("Unable to instantiate proxy from generated proxy class.", e);
- }
- }
-
- public Object createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
- Class[] proxyClasses)
- {
- try
- {
- final Class clazz = interceptorProxyClassCache.getProxyClass(classLoader, proxyClasses);
- return clazz.getConstructor(new Class[]{Object.class, Interceptor.class})
- .newInstance(new Object[]{target, interceptor});
- }
- catch (Exception e)
- {
- throw new ProxyFactoryException("Unable to instantiate proxy class instance.", e);
- }
- }
-
- public Object createInvokerProxy(ClassLoader classLoader, Invoker invoker,
- Class[] proxyClasses)
- {
- try
- {
- final Class clazz = invocationHandlerProxyClassCache.getProxyClass(classLoader, proxyClasses);
- return clazz.getConstructor(new Class[]{Invoker.class})
- .newInstance(new Object[]{invoker});
- }
- catch (Exception e)
- {
- throw new ProxyFactoryException("Unable to instantiate proxy from generated proxy class.", e);
- }
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class DelegatingProxyClassGenerator extends AbstractProxyClassGenerator
- {
- public Class generateProxyClass(ClassLoader classLoader, Class[] proxyClasses)
- {
- try
- {
- final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
- JavassistUtils.addField(ObjectProvider.class, "provider", proxyClass);
- final CtConstructor proxyConstructor = new CtConstructor(
- JavassistUtils.resolve(new Class[]{ObjectProvider.class}),
- proxyClass);
- proxyConstructor.setBody("{ this.provider = $1; }");
- proxyClass.addConstructor(proxyConstructor);
- JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
- addHashCodeMethod(proxyClass);
- addEqualsMethod(proxyClass);
- final Method[] methods = getImplementationMethods(proxyClasses);
- for (int i = 0; i < methods.length; ++i)
- {
- if (!isEqualsMethod(methods[i]) && !isHashCode(methods[i]))
- {
- final Method method = methods[i];
- final CtMethod ctMethod = new CtMethod(JavassistUtils.resolve(method.getReturnType()),
- method.getName(),
- JavassistUtils.resolve(method.getParameterTypes()),
- proxyClass);
- final String body = "{ return ( $r ) ( ( " + method.getDeclaringClass().getName() +
- " )provider.getObject() )." +
- method.getName() + "($$); }";
- ctMethod.setBody(body);
- proxyClass.addMethod(ctMethod);
- }
- }
- return proxyClass.toClass(classLoader);
- }
- catch (CannotCompileException e)
- {
- throw new ProxyFactoryException("Could not compile class.", e);
- }
- }
- }
-
- private static class InterceptorProxyClassGenerator extends AbstractProxyClassGenerator
- {
- public Class generateProxyClass(ClassLoader classLoader, Class[] proxyClasses)
- {
- try
- {
- final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
- final Method[] methods = getImplementationMethods(proxyClasses);
- JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
- JavassistUtils.addField(Object.class, "target", proxyClass);
- JavassistUtils.addField(Interceptor.class, "interceptor", proxyClass);
- addGetMethodMethod(proxyClass);
- addHashCodeMethod(proxyClass);
- addEqualsMethod(proxyClass);
- final CtConstructor proxyConstructor = new CtConstructor(
- JavassistUtils.resolve(
- new Class[]{Object.class, Interceptor.class}),
- proxyClass);
- proxyConstructor
- .setBody(
- "{\n\tthis.target = $1;\n\tthis.interceptor = $2; }");
- proxyClass.addConstructor(proxyConstructor);
- for (int i = 0; i < methods.length; ++i)
- {
- if (!isEqualsMethod(methods[i]) && !isHashCode(methods[i]))
- {
- final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
- methods[i].getName(),
- JavassistUtils.resolve(methods[i].getParameterTypes()),
- proxyClass);
- final Class invocationClass = JavassistInvocation
- .getMethodInvocationClass(classLoader, methods[i]);
-
- final String body = "{\n\t return ( $r ) interceptor.intercept( new " + invocationClass.getName() +
- "( " + GET_METHOD_METHOD_NAME + "(\"" + methods[i].getDeclaringClass().getName() +
- "\", \"" + methods[i].getName() + "\", $sig), target, $args ) );\n }";
- method.setBody(body);
- proxyClass.addMethod(method);
- }
-
- }
- return proxyClass.toClass(classLoader);
- }
- catch (CannotCompileException e)
- {
- throw new ProxyFactoryException("Could not compile class.", e);
- }
- }
-
-
- }
-
- private static void addEqualsMethod(CtClass proxyClass)
- throws CannotCompileException
- {
- final CtMethod equalsMethod = new CtMethod(JavassistUtils.resolve(Boolean.TYPE), "equals",
- JavassistUtils.resolve(new Class[]{Object.class}), proxyClass);
- final String body = "{\n\treturn this == $1;\n}";
- equalsMethod.setBody(body);
- proxyClass.addMethod(equalsMethod);
- }
-
- private static void addHashCodeMethod(CtClass proxyClass)
- throws CannotCompileException
- {
- final CtMethod hashCodeMethod = new CtMethod(JavassistUtils.resolve(Integer.TYPE), "hashCode",
- new CtClass[0], proxyClass);
- hashCodeMethod.setBody("{\n\treturn System.identityHashCode(this);\n}");
- proxyClass.addMethod(hashCodeMethod);
- }
-
- private static class InvokerProxyClassGenerator extends AbstractProxyClassGenerator
- {
- public Class generateProxyClass(ClassLoader classLoader, Class[] proxyClasses)
- {
- try
- {
- final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
- final Method[] methods = getImplementationMethods(proxyClasses);
- JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
- JavassistUtils.addField(Invoker.class, "invoker", proxyClass);
- final CtConstructor proxyConstructor = new CtConstructor(
- JavassistUtils.resolve(
- new Class[]{Invoker.class}),
- proxyClass);
- proxyConstructor
- .setBody("{\n\tthis.invoker = $1; }");
- proxyClass.addConstructor(proxyConstructor);
- addGetMethodMethod(proxyClass);
- addHashCodeMethod(proxyClass);
- addEqualsMethod(proxyClass);
- for (int i = 0; i < methods.length; ++i)
- {
- if (!isEqualsMethod(methods[i]) && !isHashCode(methods[i]))
- {
- final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
- methods[i].getName(),
- JavassistUtils.resolve(methods[i].getParameterTypes()),
- proxyClass);
- final String body = "{\n\t return ( $r ) invoker.invoke( this, " + GET_METHOD_METHOD_NAME + "(\"" +
- methods[i].getDeclaringClass().getName() +
- "\", \"" + methods[i].getName() + "\", $sig), $args );\n }";
- method.setBody(body);
- proxyClass.addMethod(method);
- }
- }
- return proxyClass.toClass(classLoader);
- }
- catch (CannotCompileException e)
- {
- throw new ProxyFactoryException("Could not compile class.", e);
- }
- }
- }
-}
-
+/*
+ * 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.javassist;
+
+import javassist.CannotCompileException;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import org.apache.commons.proxy2.Interceptor;
+import org.apache.commons.proxy2.Invoker;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.exception.ProxyFactoryException;
+import org.apache.commons.proxy2.impl.AbstractProxyClassGenerator;
+import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;
+import org.apache.commons.proxy2.impl.ProxyClassCache;
+
+import java.lang.reflect.Method;
+
+public class JavassistProxyFactory extends AbstractSubclassingProxyFactory
+{
+ //**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ private static final String GET_METHOD_METHOD_NAME = "_javassistGetMethod";
+
+ private static final ProxyClassCache DELEGATING_PROXY_CACHE = new ProxyClassCache(
+ new DelegatingProxyClassGenerator());
+ private static final ProxyClassCache INTERCEPTOR_PROXY_CACHE = new ProxyClassCache(
+ new InterceptorProxyClassGenerator());
+ private static final ProxyClassCache INVOKER_PROXY_CACHE = new ProxyClassCache(
+ new InvokerProxyClassGenerator());
+
+//**********************************************************************************************************************
+// Static Methods
+//**********************************************************************************************************************
+
+ private static void addGetMethodMethod(CtClass proxyClass) throws CannotCompileException
+ {
+ final CtMethod method = new CtMethod(JavassistUtils.resolve(Method.class), GET_METHOD_METHOD_NAME,
+ JavassistUtils.resolve(new Class[]{String.class, String.class, Class[].class}), proxyClass);
+ final String body = "try { return Class.forName($1).getMethod($2, $3); } catch( Exception e ) " +
+ "{ throw new RuntimeException(\"Unable to look up method.\", e); }";
+ method.setBody(body);
+ proxyClass.addMethod(method);
+ }
+
+ //**********************************************************************************************************************
+ // ProxyFactory Implementation
+ //**********************************************************************************************************************
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> targetProvider,
+ Class<?>... proxyClasses)
+ {
+ try
+ {
+ final Class<? extends T> clazz = (Class<? extends T>) DELEGATING_PROXY_CACHE.getProxyClass(classLoader, proxyClasses);
+ return clazz.getConstructor(ObjectProvider.class)
+ .newInstance(targetProvider);
+ }
+ catch (Exception e)
+ {
+ throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
+ Class<?>... proxyClasses)
+ {
+ try
+ {
+ final Class<? extends T> clazz = (Class<? extends T>) INTERCEPTOR_PROXY_CACHE.getProxyClass(classLoader, proxyClasses);
+ return clazz.getConstructor(Object.class, Interceptor.class)
+ .newInstance(target, interceptor);
+ }
+ catch (Exception e)
+ {
+ throw new ProxyFactoryException("Unable to instantiate proxy2 class instance.", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker,
+ Class<?>... proxyClasses)
+ {
+ try
+ {
+ final Class<? extends T> clazz = (Class<? extends T>) INVOKER_PROXY_CACHE.getProxyClass(classLoader, proxyClasses);
+ return clazz.getConstructor(Invoker.class)
+ .newInstance(invoker);
+ }
+ catch (Exception e)
+ {
+ throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);
+ }
+ }
+
+//**********************************************************************************************************************
+// Inner Classes
+//**********************************************************************************************************************
+
+ private static class DelegatingProxyClassGenerator extends AbstractProxyClassGenerator
+ {
+ public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)
+ {
+ try
+ {
+ final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
+ JavassistUtils.addField(ObjectProvider.class, "provider", proxyClass);
+ final CtConstructor proxyConstructor = new CtConstructor(
+ JavassistUtils.resolve(new Class[]{ObjectProvider.class}),
+ proxyClass);
+ proxyConstructor.setBody("{ this.provider = $1; }");
+ proxyClass.addConstructor(proxyConstructor);
+ JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
+ addHashCodeMethod(proxyClass);
+ addEqualsMethod(proxyClass);
+ final Method[] methods = getImplementationMethods(proxyClasses);
+ for (int i = 0; i < methods.length; ++i)
+ {
+ if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
+ {
+ final Method method = methods[i];
+ final CtMethod ctMethod = new CtMethod(JavassistUtils.resolve(method.getReturnType()),
+ method.getName(),
+ JavassistUtils.resolve(method.getParameterTypes()),
+ proxyClass);
+ final String body = "{ return ( $r ) ( ( " + method.getDeclaringClass().getName() +
+ " )provider.getObject() )." +
+ method.getName() + "($$); }";
+ ctMethod.setBody(body);
+ proxyClass.addMethod(ctMethod);
+ }
+ }
+ return proxyClass.toClass(classLoader);
+ }
+ catch (CannotCompileException e)
+ {
+ throw new ProxyFactoryException("Could not compile class.", e);
+ }
+ }
+ }
+
+ private static class InterceptorProxyClassGenerator extends AbstractProxyClassGenerator
+ {
+ public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)
+ {
+ try
+ {
+ final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
+ final Method[] methods = getImplementationMethods(proxyClasses);
+ JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
+ JavassistUtils.addField(Object.class, "target", proxyClass);
+ JavassistUtils.addField(Interceptor.class, "interceptor", proxyClass);
+ addGetMethodMethod(proxyClass);
+ addHashCodeMethod(proxyClass);
+ addEqualsMethod(proxyClass);
+ final CtConstructor proxyConstructor = new CtConstructor(
+ JavassistUtils.resolve(
+ new Class[]{Object.class, Interceptor.class}),
+ proxyClass);
+ proxyConstructor
+ .setBody(
+ "{\n\tthis.target = $1;\n\tthis.interceptor = $2; }");
+ proxyClass.addConstructor(proxyConstructor);
+ for (int i = 0; i < methods.length; ++i)
+ {
+ if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
+ {
+ final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
+ methods[i].getName(),
+ JavassistUtils.resolve(methods[i].getParameterTypes()),
+ proxyClass);
+ final Class<?> invocationClass = JavassistInvocation
+ .getMethodInvocationClass(classLoader, methods[i]);
+
+ final String body = "{\n\t return ( $r ) interceptor.intercept( new " + invocationClass.getName() +
+ "( this, target, " + GET_METHOD_METHOD_NAME + "(\"" + methods[i].getDeclaringClass().getName() +
+ "\", \"" + methods[i].getName() + "\", $sig), $args ) );\n }";
+ method.setBody(body);
+ proxyClass.addMethod(method);
+ }
+
+ }
+ return proxyClass.toClass(classLoader);
+ }
+ catch (CannotCompileException e)
+ {
+ throw new ProxyFactoryException("Could not compile class.", e);
+ }
+ }
+
+
+ }
+
+ private static void addEqualsMethod(CtClass proxyClass)
+ throws CannotCompileException
+ {
+ final CtMethod equalsMethod = new CtMethod(JavassistUtils.resolve(Boolean.TYPE), "equals",
+ JavassistUtils.resolve(new Class[]{Object.class}), proxyClass);
+ final String body = "{\n\treturn this == $1;\n}";
+ equalsMethod.setBody(body);
+ proxyClass.addMethod(equalsMethod);
+ }
+
+ private static void addHashCodeMethod(CtClass proxyClass)
+ throws CannotCompileException
+ {
+ final CtMethod hashCodeMethod = new CtMethod(JavassistUtils.resolve(Integer.TYPE), "hashCode",
+ new CtClass[0], proxyClass);
+ hashCodeMethod.setBody("{\n\treturn System.identityHashCode(this);\n}");
+ proxyClass.addMethod(hashCodeMethod);
+ }
+
+ private static class InvokerProxyClassGenerator extends AbstractProxyClassGenerator
+ {
+ public Class<?> generateProxyClass(ClassLoader classLoader, Class<?>... proxyClasses)
+ {
+ try
+ {
+ final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
+ final Method[] methods = getImplementationMethods(proxyClasses);
+ JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
+ JavassistUtils.addField(Invoker.class, "invoker", proxyClass);
+ final CtConstructor proxyConstructor = new CtConstructor(
+ JavassistUtils.resolve(
+ new Class[]{Invoker.class}),
+ proxyClass);
+ proxyConstructor
+ .setBody("{\n\tthis.invoker = $1; }");
+ proxyClass.addConstructor(proxyConstructor);
+ addGetMethodMethod(proxyClass);
+ addHashCodeMethod(proxyClass);
+ addEqualsMethod(proxyClass);
+ for (int i = 0; i < methods.length; ++i)
+ {
+ if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
+ {
+ final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
+ methods[i].getName(),
+ JavassistUtils.resolve(methods[i].getParameterTypes()),
+ proxyClass);
+ final String body = "{\n\t return ( $r ) invoker.invoke( this, " + GET_METHOD_METHOD_NAME + "(\"" +
+ methods[i].getDeclaringClass().getName() +
+ "\", \"" + methods[i].getName() + "\", $sig), $args );\n }";
+ method.setBody(body);
+ proxyClass.addMethod(method);
+ }
+ }
+ return proxyClass.toClass(classLoader);
+ }
+ catch (CannotCompileException e)
+ {
+ throw new ProxyFactoryException("Could not compile class.", e);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/apache/commons/proxy/factory/javassist/JavassistUtils.java b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java
similarity index 71%
rename from src/main/java/org/apache/commons/proxy/factory/javassist/JavassistUtils.java
rename to javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java
index 1b248b4..78dc74e 100644
--- a/src/main/java/org/apache/commons/proxy/factory/javassist/JavassistUtils.java
+++ b/javassist/src/main/java/org/apache/commons/proxy2/javassist/JavassistUtils.java
@@ -1,155 +1,153 @@
-/*
- * 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.proxy.factory.javassist;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-import org.apache.commons.proxy.ProxyUtils;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Some utility methods for dealing with Javassist. This class is not part of the public API!
- *
- * @author James Carman
- * @since 1.0
- */
-class JavassistUtils
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- public static final String DEFAULT_BASE_NAME = "JavassistUtilsGenerated";
- private static int classNumber = 0;
- private static final ClassPool classPool = new ClassPool();
-
- private static final Set classLoaders = new HashSet();
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- static
- {
- classPool.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader()));
- }
-
- /**
- * Adds a field to a class.
- *
- * @param fieldType the field's type
- * @param fieldName the field name
- * @param enclosingClass the class receiving the new field
- * @throws CannotCompileException if a compilation problem occurs
- */
- public static void addField( Class fieldType, String fieldName, CtClass enclosingClass )
- throws CannotCompileException
- {
- enclosingClass.addField(new CtField(resolve(fieldType), fieldName, enclosingClass));
- }
-
- /**
- * Adds interfaces to a {@link CtClass}
- *
- * @param ctClass the {@link CtClass}
- * @param proxyClasses the interfaces
- */
- public static void addInterfaces( CtClass ctClass, Class[] proxyClasses )
- {
- for( int i = 0; i < proxyClasses.length; i++ )
- {
- Class proxyInterface = proxyClasses[i];
- ctClass.addInterface(resolve(proxyInterface));
- }
- }
-
- /**
- * Creates a new {@link CtClass} derived from the Java {@link Class} using the default base name.
- *
- * @param superclass the superclass
- * @return the new derived {@link CtClass}
- */
- public static CtClass createClass( Class superclass )
- {
- return createClass(DEFAULT_BASE_NAME, superclass);
- }
-
- /**
- * Creates a new {@link CtClass} derived from the Java {@link Class} using the supplied base name.
- *
- * @param baseName the base name
- * @param superclass the superclass
- * @return the new derived {@link CtClass}
- */
- public synchronized static CtClass createClass( String baseName, Class superclass )
- {
- return classPool.makeClass(baseName + "_" + classNumber++, resolve(superclass));
- }
-
- /**
- * Finds the {@link CtClass} corresponding to the Java {@link Class} passed in.
- *
- * @param clazz the Java {@link Class}
- * @return the {@link CtClass}
- */
- public static CtClass resolve( Class clazz )
- {
- synchronized( classLoaders )
- {
- try
- {
- final ClassLoader loader = clazz.getClassLoader();
- if( loader != null && !classLoaders.contains(loader) )
- {
- classLoaders.add(loader);
- classPool.appendClassPath(new LoaderClassPath(loader));
- }
- return classPool.get(ProxyUtils.getJavaClassName(clazz));
- }
- catch( NotFoundException e )
- {
- throw new ObjectProviderException(
- "Unable to find class " + clazz.getName() + " in default Javassist class pool.", e);
- }
- }
- }
-
- /**
- * Resolves an array of Java {@link Class}es to an array of their corresponding {@link CtClass}es.
- *
- * @param classes the Java {@link Class}es
- * @return the corresponding {@link CtClass}es
- */
- public static CtClass[] resolve( Class[] classes )
- {
- final CtClass[] ctClasses = new CtClass[classes.length];
- for( int i = 0; i < ctClasses.length; ++i )
- {
- ctClasses[i] = resolve(classes[i]);
- }
- return ctClasses;
- }
-}
-
+/*
+ * 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.javassist;
+
+import javassist.*;
+import org.apache.commons.proxy2.ProxyUtils;
+import org.apache.commons.proxy2.exception.ObjectProviderException;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Some utility methods for dealing with Javassist. This class is not part of the public API!
+ *
+ * @author James Carman
+ * @since 1.0
+ */
+final class JavassistUtils
+{
+//**********************************************************************************************************************
+// Fields
+//**********************************************************************************************************************
+
+ public static final String DEFAULT_BASE_NAME = "JavassistUtilsGenerated";
+ private static final AtomicInteger CLASS_NUMBER = new AtomicInteger(0);
+ private static final ClassPool CLASS_POOL = new ClassPool();
+ private static final Set<ClassLoader> CLASS_LOADERS = new HashSet<ClassLoader>();
+
+//**********************************************************************************************************************
+// Static Methods
+//**********************************************************************************************************************
+
+ static
+ {
+ CLASS_POOL.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader()));
+ }
+
+ /**
+ * Adds a field to a class.
+ *
+ * @param fieldType the field's type
+ * @param fieldName the field name
+ * @param enclosingClass the class receiving the new field
+ * @throws CannotCompileException if a compilation problem occurs
+ */
+ public static void addField( Class<?> fieldType, String fieldName, CtClass enclosingClass )
+ throws CannotCompileException
+ {
+ enclosingClass.addField(new CtField(resolve(fieldType), fieldName, enclosingClass));
+ }
+
+ /**
+ * Adds interfaces to a {@link CtClass}
+ *
+ * @param ctClass the {@link CtClass}
+ * @param proxyClasses the interfaces
+ */
+ public static void addInterfaces( CtClass ctClass, Class<?>[] proxyClasses )
+ {
+ for( int i = 0; i < proxyClasses.length; i++ )
+ {
+ Class<?> proxyInterface = proxyClasses[i];
+ ctClass.addInterface(resolve(proxyInterface));
+ }
+ }
+
+ /**
+ * Creates a new {@link CtClass} derived from the Java {@link Class} using the default base name.
+ *
+ * @param superclass the superclass
+ * @return the new derived {@link CtClass}
+ */
+ public static CtClass createClass( Class<?> superclass )
+ {
+ return createClass(DEFAULT_BASE_NAME, superclass);
+ }
+
+ /**
+ * Creates a new {@link CtClass} derived from the Java {@link Class} using the supplied base name.
+ *
+ * @param baseName the base name
+ * @param superclass the superclass
+ * @return the new derived {@link CtClass}
+ */
+ public static synchronized CtClass createClass( String baseName, Class<?> superclass )
+ {
+ return CLASS_POOL.makeClass(baseName + "_" + CLASS_NUMBER.incrementAndGet(), resolve(superclass));
+ }
+
+ /**
+ * Finds the {@link CtClass} corresponding to the Java {@link Class} passed in.
+ *
+ * @param clazz the Java {@link Class}
+ * @return the {@link CtClass}
+ */
+ public static CtClass resolve( Class<?> clazz )
+ {
+ synchronized(CLASS_LOADERS)
+ {
+ try
+ {
+ final ClassLoader loader = clazz.getClassLoader();
+ if( loader != null && !CLASS_LOADERS.contains(loader) )
+ {
+ CLASS_LOADERS.add(loader);
+ CLASS_POOL.appendClassPath(new LoaderClassPath(loader));
+ }
+ return CLASS_POOL.get(ProxyUtils.getJavaClassName(clazz));
+ }
+ catch( NotFoundException e )
+ {
+ throw new ObjectProviderException(
+ "Unable to find class " + clazz.getName() + " in default Javassist class pool.", e);
+ }
+ }
+ }
+
+ /**
+ * Resolves an array of Java {@link Class}es to an array of their corresponding {@link CtClass}es.
+ *
+ * @param classes the Java {@link Class}es
+ * @return the corresponding {@link CtClass}es
+ */
+ public static CtClass[] resolve( Class<?>[] classes )
+ {
+ final CtClass[] ctClasses = new CtClass[classes.length];
+ for( int i = 0; i < ctClasses.length; ++i )
+ {
+ ctClasses[i] = resolve(classes[i]);
+ }
+ return ctClasses;
+ }
+
+ private JavassistUtils() {
+ // Hiding constructor in utility class!
+ }
+}
diff --git a/src/test/resources/log4j.properties b/javassist/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
similarity index 75%
copy from src/test/resources/log4j.properties
copy to javassist/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
index b981287..283b11a 100644
--- a/src/test/resources/log4j.properties
+++ b/javassist/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
@@ -1,20 +1,17 @@
-#
-# 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.
-#
-log4j.rootLogger=DEBUG, console
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p (%c{1}) %3x - %m%n
\ No newline at end of file
+#
+# 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.
+#
+org.apache.commons.proxy2.javassist.JavassistProxyFactory
\ No newline at end of file
diff --git a/javassist/src/site/markdown/index.md b/javassist/src/site/markdown/index.md
new file mode 100644
index 0000000..13391dc
--- /dev/null
+++ b/javassist/src/site/markdown/index.md
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+
+## Commons Proxy Javassist
+
+Provides the [JavassistProxyFactory][] which uses the [Javassist][] library
+to create proxy classes. This proxy factory is capable of proxying concrete
+non-`final` types and can thus be considered a *subclassing* proxy factory.
+
+[JavassistProxyFactory]: apidocs/org/apache/commons/proxy2/javassist/JavassistProxyFactory.html
+[Javassist]: http://www.javassist.org
diff --git a/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java b/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java
new file mode 100644
index 0000000..9eeea9e
--- /dev/null
+++ b/javassist/src/test/java/org/apache/commons/proxy2/javassist/JavassistProxyFactoryTest.java
@@ -0,0 +1,10 @@
+package org.apache.commons.proxy2.javassist;
+
+import org.apache.commons.proxy2.AbstractSubclassingProxyFactoryTestCase;
+
+public class JavassistProxyFactoryTest extends AbstractSubclassingProxyFactoryTestCase
+{
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+}
diff --git a/jdk/pom.xml b/jdk/pom.xml
new file mode 100644
index 0000000..a6ef879
--- /dev/null
+++ b/jdk/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy2-jdk</artifactId>
+ <name>Commons Proxy JDK Proxies Module</name>
+ <description>Interface-based proxies using the core JDK Proxy mechanism
+ </description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java b/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java
new file mode 100644
index 0000000..cc4ff4e
--- /dev/null
+++ b/jdk/src/main/java/org/apache/commons/proxy2/jdk/JdkProxyFactory.java
@@ -0,0 +1,225 @@
+/*
+ * 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.jdk;
+
+import org.apache.commons.proxy2.*;
+import org.apache.commons.proxy2.impl.AbstractProxyFactory;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * {@link ProxyFactory} implementation that uses {@link java.lang.reflect.Proxy} proxies.
+ */
+public class JdkProxyFactory extends AbstractProxyFactory
+{
+//**********************************************************************************************************************
+// ProxyFactory Implementation
+//**********************************************************************************************************************
+
+ /**
+ * Creates a proxy2 which delegates to the object provided by <code>delegateProvider</code>.
+ *
+ * @param classLoader the class loader to use when generating the proxy2
+ * @param delegateProvider the delegate provider
+ * @param proxyClasses the interfaces that the proxy2 should implement
+ * @return a proxy2 which delegates to the object provided by the target <code>delegateProvider>
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createDelegatorProxy( ClassLoader classLoader, ObjectProvider<?> delegateProvider,
+ Class<?>... proxyClasses )
+ {
+ return (T) Proxy.newProxyInstance(classLoader, proxyClasses,
+ new DelegatorInvocationHandler(delegateProvider));
+ }
+
+ /**
+ * Creates a proxy2 which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object.
+ *
+ * @param classLoader the class loader to use when generating the proxy2
+ * @param target the target object
+ * @param interceptor the method interceptor
+ * @param proxyClasses the interfaces that the proxy2 should implement.
+ * @return a proxy2 which passes through a {@link Interceptor interceptor} before eventually reaching the
+ * <code>target</code> object.
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createInterceptorProxy( ClassLoader classLoader, Object target, Interceptor interceptor,
+ Class<?>... proxyClasses )
+ {
+ return (T) Proxy
+ .newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(target, interceptor));
+ }
+
+ /**
+ * Creates a proxy2 which uses the provided {@link Invoker} to handle all method invocations.
+ *
+ * @param classLoader the class loader to use when generating the proxy2
+ * @param invoker the invoker
+ * @param proxyClasses the interfaces that the proxy2 should implement
+ * @return a proxy2 which uses the provided {@link Invoker} to handle all method invocations
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T createInvokerProxy( ClassLoader classLoader, Invoker invoker,
+ Class<?>... proxyClasses )
+ {
+ return (T) Proxy.newProxyInstance(classLoader, proxyClasses, new InvokerInvocationHandler(invoker));
+ }
+
+//**********************************************************************************************************************
+// Inner Classes
+//**********************************************************************************************************************
+
+ private abstract static class AbstractInvocationHandler implements InvocationHandler, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
+ {
+ if( ProxyUtils.isHashCode(method) )
+ {
+ return System.identityHashCode(proxy);
+ }
+ else if( ProxyUtils.isEqualsMethod(method) )
+ {
+ return proxy == args[0];
+ }
+ else
+ {
+ return invokeImpl(proxy, method, args);
+ }
+ }
+
+ protected abstract Object invokeImpl( Object proxy, Method method, Object[] args ) throws Throwable;
+ }
+
+ private static class DelegatorInvocationHandler extends AbstractInvocationHandler
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final ObjectProvider<?> delegateProvider;
+
+ protected DelegatorInvocationHandler( ObjectProvider<?> delegateProvider )
+ {
+ this.delegateProvider = delegateProvider;
+ }
+
+ public Object invokeImpl( Object proxy, Method method, Object[] args ) throws Throwable
+ {
+ try
+ {
+ return method.invoke(delegateProvider.getObject(), args);
+ }
+ catch( InvocationTargetException e )
+ {
+ throw e.getTargetException();
+ }
+ }
+ }
+
+ private static class InterceptorInvocationHandler extends AbstractInvocationHandler
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Object target;
+ private final Interceptor methodInterceptor;
+
+ public InterceptorInvocationHandler( Object target, Interceptor methodInterceptor )
+ {
+ this.target = target;
+ this.methodInterceptor = methodInterceptor;
+ }
+
+ public Object invokeImpl( Object proxy, Method method, Object[] args ) throws Throwable
+ {
+ final ReflectionInvocation invocation = new ReflectionInvocation(proxy, target, method, args);
+ return methodInterceptor.intercept(invocation);
+ }
+ }
+
+ private static class InvokerInvocationHandler extends AbstractInvocationHandler
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Invoker invoker;
+
+ public InvokerInvocationHandler( Invoker invoker )
+ {
+ this.invoker = invoker;
+ }
+
+ public Object invokeImpl( Object proxy, Method method, Object[] args ) throws Throwable
+ {
+ return invoker.invoke(proxy, method, args);
+ }
+ }
+
+ private static class ReflectionInvocation implements Invocation, Serializable
+ {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final Object proxy;
+ private final Object target;
+ private final Method method;
+ private final Object[] arguments;
+
+ public ReflectionInvocation( Object proxy, Object target, Method method, Object[] arguments )
+ {
+ this.proxy = proxy;
+ this.target = target;
+ this.method = method;
+ this.arguments = ( arguments == null ? ProxyUtils.EMPTY_ARGUMENTS : arguments );
+ }
+
+ public Object[] getArguments()
+ {
+ return arguments;
+ }
+
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public Object getProxy()
+ {
+ return proxy;
+ }
+
+ public Object proceed() throws Throwable
+ {
+ try
+ {
+ return method.invoke(target, arguments);
+ }
+ catch( InvocationTargetException e )
+ {
+ throw e.getTargetException();
+ }
+ }
+ }
+}
diff --git a/src/test/resources/log4j.properties b/jdk/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
similarity index 75%
copy from src/test/resources/log4j.properties
copy to jdk/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
index b981287..a27a58d 100644
--- a/src/test/resources/log4j.properties
+++ b/jdk/src/main/resources/META-INF/services/org.apache.commons.proxy2.ProxyFactory
@@ -1,20 +1,17 @@
-#
-# 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.
-#
-log4j.rootLogger=DEBUG, console
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p (%c{1}) %3x - %m%n
\ No newline at end of file
+#
+# 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.
+#
+org.apache.commons.proxy2.jdk.JdkProxyFactory
\ No newline at end of file
diff --git a/jdk/src/site/markdown/index.md b/jdk/src/site/markdown/index.md
new file mode 100644
index 0000000..200a724
--- /dev/null
+++ b/jdk/src/site/markdown/index.md
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+## Commons Proxy JDK
+
+Uses the [Proxy][] mechanism provided by the core JDK to create
+dynamic proxy instances. This proxy factory exposes interfaces
+only.
+
+[Proxy]: http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html
diff --git a/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java b/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java
new file mode 100644
index 0000000..f157a25
--- /dev/null
+++ b/jdk/src/test/java/org/apache/commons/proxy2/jdk/JdkProxyFactoryTest.java
@@ -0,0 +1,7 @@
+package org.apache.commons.proxy2.jdk;
+
+import org.apache.commons.proxy2.AbstractProxyFactoryTestCase;
+
+public class JdkProxyFactoryTest extends AbstractProxyFactoryTestCase
+{
+}
diff --git a/pom.xml b/pom.xml
index ac007f6..4412469 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,35 +1,44 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
+
<!--
- ~ 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
+ ~ 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
+ ~ 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.
+ ~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <modules>
+ <module>core</module>
+ <module>jdk</module>
+ <module>asm4</module>
+ <module>javassist</module>
+ <module>cglib</module>
+ <module>build-tools</module>
+ <module>test</module>
+ </modules>
<parent>
<groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId>
- <version>32</version>
+ <version>25</version>
</parent>
- <artifactId>commons-proxy</artifactId>
- <version>1.1-SNAPSHOT</version>
- <name>Apache Commons Proxy</name>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <name>Commons Proxy Parent</name>
<description>Java library for dynamic proxying</description>
- <url>http://commons.apache.org/proper/commons-proxy/</url>
+ <url>http://commons.apache.org/proxy/</url>
<inceptionYear>2005</inceptionYear>
<issueManagement>
@@ -71,19 +80,17 @@
</roles>
<url></url>
</developer>
+ <developer>
+ <name>Matt Benson</name>
+ <email>mbenson@apache.org</email>
+ <roles>
+ <role>developer</role>
+ </roles>
+ </developer>
</developers>
<contributors>
<contributor>
- <name>Jörg Schaible</name>
- <email>joerg.schaible@gmx.de</email>
- <organization/>
- <roles>
- <role>advisor</role>
- </roles>
- <url></url>
- </contributor>
- <contributor>
<name>Howard M. Lewis Ship</name>
<email>hlship@apache.org</email>
<organization/>
@@ -92,6 +99,20 @@
</roles>
<url>http://www.howardlewisship.com/</url>
</contributor>
+ <contributor>
+ <name>Jörg Schaible</name>
+ <email>joerg.schaible@gmx.de</email>
+ <organization/>
+ <roles>
+ <role>advisor</role>
+ </roles>
+ </contributor>
+ <contributor>
+ <name>Mark Struberg</name>
+ </contributor>
+ <contributor>
+ <name>Romain Manni-Bucau</name>
+ </contributor>
</contributors>
<scm>
@@ -101,6 +122,14 @@
</scm>
<build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ </resources>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
@@ -114,132 +143,59 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-scm-publish-plugin</artifactId>
- <configuration>
- <ignorePathsToDelete>
- <ignorePathToDelete>javadocs</ignorePathToDelete>
- </ignorePathsToDelete>
- </configuration>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2-build-tools</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.3</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-module-markdown</artifactId>
+ <version>1.3</version>
+ </dependency>
+ </dependencies>
</plugin>
</plugins>
</build>
- <dependencies>
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib-nodep</artifactId>
- <version>2.1_3</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>jboss</groupId>
- <artifactId>javassist</artifactId>
- <version>3.0</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>aopalliance</groupId>
- <artifactId>aopalliance</artifactId>
- <version>1.0</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>axis</groupId>
- <artifactId>axis-jaxrpc</artifactId>
- <version>1.2.1</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>hessian</groupId>
- <artifactId>hessian</artifactId>
- <version>3.0.1</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>burlap</groupId>
- <artifactId>burlap</artifactId>
- <version>2.1.7</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.0.4</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.4.3</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>3.1</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>concurrent</groupId>
- <artifactId>concurrent</artifactId>
- <version>1.3.4</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>jmock</groupId>
- <artifactId>jmock</artifactId>
- <version>1.0.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>xmlrpc</groupId>
- <artifactId>xmlrpc</artifactId>
- <version>2.0</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>1.3</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.3</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
- <version>2.1</version>
<configuration>
- <configLocation>${basedir}/checkstyle.xml</configLocation>
- <enableRulesSummary>false</enableRulesSummary>
- <headerFile>${basedir}/license-header.txt</headerFile>
+ <configLocation>org/apache/commons/proxy2/checkstyle.xml</configLocation>
+ <headerLocation>org/apache/commons/proxy2/license-header.txt</headerLocation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>2.5</version>
+
<configuration>
<linksource>true</linksource>
<links>
- <link>http://download.oracle.com/javase/1.4.2/docs/api/</link>
+ <link>http://java.sun.com/j2se/1.4.2/docs/api/</link>
<link>http://ws.apache.org/xmlrpc/apidocs/</link>
<link>http://www.csg.is.titech.ac.jp/~chiba/javassist/html</link>
- <link>http://aopalliance.sourceforge.net/doc/</link>
- <link>http://gee.cs.oswego.edu/dl/classes/</link>
- <link>http://commons.apache.org/logging/apidocs/</link>
- <link>http://www.slf4j.org/api/</link>
</links>
</configuration>
-
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <configuration>
+ <aggregate>true</aggregate>
+ </configuration>
</plugin>
</plugins>
</reporting>
@@ -252,30 +208,54 @@
</site>
</distributionManagement>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib-nodep</artifactId>
+ <version>2.1_3</version>
+ </dependency>
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>${asm.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm-commons</artifactId>
+ <version>${asm.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>jmock</groupId>
+ <artifactId>jmock</artifactId>
+ <version>1.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<properties>
- <maven.compiler.source>1.4</maven.compiler.source>
- <maven.compiler.target>1.4</maven.compiler.target>
+ <maven.compile.source>1.6</maven.compile.source>
+ <maven.compile.target>1.6</maven.compile.target>
<commons.componentid>proxy</commons.componentid>
<commons.release.version>1.0</commons.release.version>
<commons.binary.suffix></commons.binary.suffix>
<commons.jira.id>PROXY</commons.jira.id>
<commons.jira.pid>12310731</commons.jira.pid>
- <releaseManager>${user.name}</releaseManager>
+ <asm.version>4.1</asm.version>
</properties>
-
- <profiles>
- <profile>
- <id>rc</id>
- <distributionManagement>
- <site>
- <id>stagingSite</id>
- <name>Release Candidate Staging Site</name>
- <url>
- ${commons.deployment.protocol}://people.apache.org/home/${releaseManager}/public_html/${artifactId}-${version}
- </url>
- </site>
- </distributionManagement>
- </profile>
- </profiles>
-
</project>
diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml
index 5762291..ba78bbd 100644
--- a/src/assembly/bin.xml
+++ b/src/assembly/bin.xml
@@ -1,19 +1,20 @@
<!--
- 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
+ ~ 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.
+ -->
- 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.
--->
<assembly>
<id>bin</id>
<formats>
diff --git a/src/assembly/src.xml b/src/assembly/src.xml
index 0d0ac18..5a7cc0d 100644
--- a/src/assembly/src.xml
+++ b/src/assembly/src.xml
@@ -1,19 +1,20 @@
<!--
- 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
+ ~ 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.
+ -->
- 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.
--->
<assembly>
<id>src</id>
<formats>
diff --git a/src/main/java/org/apache/commons/proxy/ProxyFactory.java b/src/main/java/org/apache/commons/proxy/ProxyFactory.java
deleted file mode 100644
index 3c4fc69..0000000
--- a/src/main/java/org/apache/commons/proxy/ProxyFactory.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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.proxy;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-/**
- * A <code>ProxyFactory</code> can be used to create three different "flavors" of proxy objects.
- * <p/>
- * <ul>
- * <li>Delegator - the proxy will delegate to an object provided by an {@link ObjectProvider}</li>
- * <li>Interceptor - the proxy will pass each method invocation through an {@link Interceptor}</li>
- * <li>Invoker - the proxy will allow an {@link Invoker} to handle all method invocations</li>
- * </ul>
- * <p/>
- * <p>
- * Originally, the ProxyFactory class was an interface. However, to allow for future changes to the
- * class without breaking binary or semantic compatibility, it has been changed to a concrete class.
- * <p/>
- * </p>
- * <p>
- * <b>Note</b>: This class uses Java reflection. For more efficient proxies, try using either
- * {@link org.apache.commons.proxy.factory.cglib.CglibProxyFactory CglibProxyFactory} or
- * {@link org.apache.commons.proxy.factory.javassist.JavassistProxyFactory JavassistProxyFactory} instead.
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class ProxyFactory
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * Returns true if all <code>proxyClasses</code> are interfaces.
- *
- * @param proxyClasses the proxy classes
- * @return true if all <code>proxyClasses</code> are interfaces
- */
- public boolean canProxy(Class[] proxyClasses)
- {
- for (int i = 0; i < proxyClasses.length; i++)
- {
- Class proxyClass = proxyClasses[i];
- if (!proxyClass.isInterface())
- {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>. The proxy will be
- * generated using the current thread's "context class loader."
- *
- * @param delegateProvider the delegate provider
- * @param proxyClasses the interfaces that the proxy should implement
- * @return a proxy which delegates to the object provided by the target object provider
- */
- public Object createDelegatorProxy(ObjectProvider delegateProvider, Class[] proxyClasses)
- {
- return createDelegatorProxy(Thread.currentThread().getContextClassLoader(), delegateProvider, proxyClasses);
- }
-
- /**
- * Creates a proxy which delegates to the object provided by <code>delegateProvider</code>.
- *
- * @param classLoader the class loader to use when generating the proxy
- * @param delegateProvider the delegate provider
- * @param proxyClasses the interfaces that the proxy should implement
- * @return a proxy which delegates to the object provided by the target <code>delegateProvider>
- */
- public Object createDelegatorProxy(ClassLoader classLoader, ObjectProvider delegateProvider,
- Class[] proxyClasses)
- {
- return Proxy.newProxyInstance(classLoader, proxyClasses,
- new DelegatorInvocationHandler(delegateProvider));
- }
-
- /**
- * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
- * <code>target</code> object. The proxy will be generated using the current thread's "context class loader."
- *
- * @param target the target object
- * @param interceptor the method interceptor
- * @param proxyClasses the interfaces that the proxy should implement
- * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
- * <code>target</code> object.
- */
- public Object createInterceptorProxy(Object target, Interceptor interceptor,
- Class[] proxyClasses)
- {
- return createInterceptorProxy(Thread.currentThread().getContextClassLoader(), target, interceptor,
- proxyClasses);
- }
-
- /**
- * Creates a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
- * <code>target</code> object.
- *
- * @param classLoader the class loader to use when generating the proxy
- * @param target the target object
- * @param interceptor the method interceptor
- * @param proxyClasses the interfaces that the proxy should implement.
- * @return a proxy which passes through a {@link Interceptor interceptor} before eventually reaching the
- * <code>target</code> object.
- */
- public Object createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
- Class[] proxyClasses)
- {
- return Proxy
- .newProxyInstance(classLoader, proxyClasses, new InterceptorInvocationHandler(target, interceptor));
- }
-
- /**
- * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations. The proxy will be
- * generated using the current thread's "context class loader."
- *
- * @param invoker the invoker
- * @param proxyClasses the interfaces that the proxy should implement
- * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
- */
- public Object createInvokerProxy(Invoker invoker, Class[] proxyClasses)
- {
- return createInvokerProxy(Thread.currentThread().getContextClassLoader(), invoker,
- proxyClasses);
- }
-
- /**
- * Creates a proxy which uses the provided {@link Invoker} to handle all method invocations.
- *
- * @param classLoader the class loader to use when generating the proxy
- * @param invoker the invoker
- * @param proxyClasses the interfaces that the proxy should implement
- * @return a proxy which uses the provided {@link Invoker} to handle all method invocations
- */
- public Object createInvokerProxy(ClassLoader classLoader, Invoker invoker,
- Class[] proxyClasses)
- {
- return Proxy.newProxyInstance(classLoader, proxyClasses, new InvokerInvocationHandler(invoker));
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class DelegatorInvocationHandler extends AbstractInvocationHandler
- {
- private final ObjectProvider delegateProvider;
-
- protected DelegatorInvocationHandler(ObjectProvider delegateProvider)
- {
- this.delegateProvider = delegateProvider;
- }
-
- public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
- {
- try
- {
- return method.invoke(delegateProvider.getObject(), args);
- }
- catch (InvocationTargetException e)
- {
- throw e.getTargetException();
- }
- }
- }
-
- private static class InterceptorInvocationHandler extends AbstractInvocationHandler
- {
- private final Object target;
- private final Interceptor methodInterceptor;
-
- public InterceptorInvocationHandler(Object target, Interceptor methodInterceptor)
- {
- this.target = target;
- this.methodInterceptor = methodInterceptor;
- }
-
- public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
- {
- final ReflectionInvocation invocation = new ReflectionInvocation(target, method, args);
- return methodInterceptor.intercept(invocation);
- }
- }
-
- private abstract static class AbstractInvocationHandler implements InvocationHandler, Serializable
- {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- if (isHashCode(method))
- {
- return new Integer(System.identityHashCode(proxy));
- }
- else if (isEqualsMethod(method))
- {
- return Boolean.valueOf(proxy == args[0]);
- }
- else
- {
- return invokeImpl(proxy, method, args);
- }
- }
-
- protected abstract Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable;
- }
-
- private static class InvokerInvocationHandler extends AbstractInvocationHandler
- {
- private final Invoker invoker;
-
- public InvokerInvocationHandler(Invoker invoker)
- {
- this.invoker = invoker;
- }
-
- public Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable
- {
- return invoker.invoke(proxy, method, args);
- }
- }
-
- protected static boolean isHashCode(Method method)
- {
- return "hashCode".equals(method.getName()) &&
- Integer.TYPE.equals(method.getReturnType()) &&
- method.getParameterTypes().length == 0;
- }
-
- protected static boolean isEqualsMethod(Method method)
- {
- return "equals".equals(method.getName()) &&
- Boolean.TYPE.equals(method.getReturnType()) &&
- method.getParameterTypes().length == 1 &&
- Object.class.equals(method.getParameterTypes()[0]);
- }
-
- private static class ReflectionInvocation implements Invocation, Serializable
- {
- private final Method method;
- private final Object[] arguments;
- private final Object target;
-
- public ReflectionInvocation(Object target, Method method, Object[] arguments)
- {
- this.method = method;
- this.arguments = (arguments == null ? ProxyUtils.EMPTY_ARGUMENTS : arguments);
- this.target = target;
- }
-
- public Object[] getArguments()
- {
- return arguments;
- }
-
- public Method getMethod()
- {
- return method;
- }
-
- public Object getProxy()
- {
- return target;
- }
-
- public Object proceed() throws Throwable
- {
- try
- {
- return method.invoke(target, arguments);
- }
- catch (InvocationTargetException e)
- {
- throw e.getTargetException();
- }
- }
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/ProxyUtils.java b/src/main/java/org/apache/commons/proxy/ProxyUtils.java
deleted file mode 100644
index 28e2443..0000000
--- a/src/main/java/org/apache/commons/proxy/ProxyUtils.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.proxy;
-
-import org.apache.commons.proxy.invoker.NullInvoker;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Provides some helpful proxy utility methods.
- *
- * @author James Carman
- * @since 1.0
- */
-public class ProxyUtils
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- public static final Object[] EMPTY_ARGUMENTS = new Object[0];
- public static final Class[] EMPTY_ARGUMENT_TYPES = new Class[0];
- private static final Map wrapperClassMap = new HashMap();
- public static Map defaultValueMap = new HashMap();
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- static
- {
- wrapperClassMap.put(Integer.TYPE, Integer.class);
- wrapperClassMap.put(Character.TYPE, Character.class);
- wrapperClassMap.put(Boolean.TYPE, Boolean.class);
- wrapperClassMap.put(Short.TYPE, Short.class);
- wrapperClassMap.put(Long.TYPE, Long.class);
- wrapperClassMap.put(Float.TYPE, Float.class);
- wrapperClassMap.put(Double.TYPE, Double.class);
- wrapperClassMap.put(Byte.TYPE, Byte.class);
- }
-
- static
- {
- defaultValueMap.put(Integer.TYPE, new Integer(0));
- defaultValueMap.put(Long.TYPE, new Long(0));
- defaultValueMap.put(Short.TYPE, new Short(( short ) 0));
- defaultValueMap.put(Byte.TYPE, new Byte(( byte ) 0));
- defaultValueMap.put(Float.TYPE, new Float(0.0f));
- defaultValueMap.put(Double.TYPE, new Double(0.0));
- defaultValueMap.put(Character.TYPE, new Character(( char ) 0));
- defaultValueMap.put(Boolean.TYPE, Boolean.FALSE);
- }
-
- /**
- * Creates a "null object" which implements the <code>proxyClasses</code>.
- *
- * @param proxyFactory the proxy factory to be used to create the proxy object
- * @param proxyClasses the proxy interfaces
- * @return a "null object" which implements the <code>proxyClasses</code>.
- */
- public static Object createNullObject( ProxyFactory proxyFactory, Class[] proxyClasses )
- {
- return proxyFactory.createInvokerProxy(new NullInvoker(), proxyClasses);
- }
-
- /**
- * Creates a "null object" which implements the <code>proxyClasses</code>.
- *
- * @param proxyFactory the proxy factory to be used to create the proxy object
- * @param classLoader the class loader to be used by the proxy factory to create the proxy object
- * @param proxyClasses the proxy interfaces
- * @return a "null object" which implements the <code>proxyClasses</code>.
- */
- public static Object createNullObject( ProxyFactory proxyFactory, ClassLoader classLoader, Class[] proxyClasses )
- {
- return proxyFactory.createInvokerProxy(classLoader, new NullInvoker(), proxyClasses);
- }
-
- /**
- * <p>Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its
- * superclasses.</p>
- * <p/>
- * <p>The order is determined by looking through each interface in turn as declared in the source file and following
- * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order
- * is maintained.</p>
- * <p/>
- * <b>Note</b>: Implementation of this method was "borrowed" from
- * <a href="http://commons.apache.org/lang/">Apache Commons Lang</a> to avoid a dependency.</p>
- *
- * @param cls the class to look up, may be <code>null</code>
- * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its
- * superclasses or <code>null</code> if input class is null.
- */
- public static Class[] getAllInterfaces( Class cls )
- {
- final List interfaces = getAllInterfacesImpl(cls, new LinkedList());
- return interfaces == null ? null : ( Class[] ) interfaces.toArray(new Class[interfaces.size()]);
- }
-
- private static List getAllInterfacesImpl( Class cls, List list )
- {
- if( cls == null )
- {
- return null;
- }
- while( cls != null )
- {
- Class[] interfaces = cls.getInterfaces();
- for( int i = 0; i < interfaces.length; i++ )
- {
- if( !list.contains(interfaces[i]) )
- {
- list.add(interfaces[i]);
- }
- getAllInterfacesImpl(interfaces[i], list);
- }
- cls = cls.getSuperclass();
- }
- return list;
- }
-
- /**
- * Returns the class name as you would expect to see it in Java code.
- * <p/>
- * <b>Examples:</b> <ul> <li>getJavaClassName( Object[].class ) == "Object[]"</li> <li>getJavaClassName(
- * Object[][].class ) == "Object[][]"</li> <li>getJavaClassName( Integer.TYPE ) == "int"</li> </p>
- *
- * @param clazz the class
- * @return the class' name as you would expect to see it in Java code
- */
- public static String getJavaClassName( Class clazz )
- {
- if( clazz.isArray() )
- {
- return getJavaClassName(clazz.getComponentType()) + "[]";
- }
- return clazz.getName();
- }
-
- /**
- * Returns the wrapper class for the given primitive type.
- *
- * @param primitiveType the primitive type
- * @return the wrapper class
- */
- public static Class getWrapperClass( Class primitiveType )
- {
- return ( Class ) wrapperClassMap.get(primitiveType);
- }
-
- /**
- * Returns the default value (null, zero, false) for a specified type.
- * @param type the type
- * @return the default value
- */
- public static Object getDefaultValue(Class type)
- {
- if( type.isPrimitive() )
- {
- return defaultValueMap.get(type);
- }
- else
- {
- return null;
- }
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/exception/InvokerException.java b/src/main/java/org/apache/commons/proxy/exception/InvokerException.java
deleted file mode 100644
index 6e98bb4..0000000
--- a/src/main/java/org/apache/commons/proxy/exception/InvokerException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.proxy.exception;
-
-/**
- * To be used by an {@link org.apache.commons.proxy.Invoker} when they encounter an error.
- *
- * @author James Carman
- * @since 1.0
- */
-public class InvokerException extends RuntimeException
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public InvokerException()
- {
- }
-
- public InvokerException( String message )
- {
- super(message);
- }
-
- public InvokerException( Throwable cause )
- {
- super(cause);
- }
-
- public InvokerException( String message, Throwable cause )
- {
- super(message, cause);
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/exception/ObjectProviderException.java b/src/main/java/org/apache/commons/proxy/exception/ObjectProviderException.java
deleted file mode 100644
index b2c35d2..0000000
--- a/src/main/java/org/apache/commons/proxy/exception/ObjectProviderException.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.proxy.exception;
-
-/**
- * {@link org.apache.commons.proxy.ObjectProvider} implementations should throw this exception type to indicate that
- * there was a problem creating/finding the object.
- *
- * @author James Carman
- * @since 1.0
- */
-public class ObjectProviderException extends RuntimeException
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ObjectProviderException()
- {
- }
-
- public ObjectProviderException( String message )
- {
- super(message);
- }
-
- public ObjectProviderException( Throwable cause )
- {
- super(cause);
- }
-
- public ObjectProviderException( String message, Throwable cause )
- {
- super(message, cause);
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/exception/package.html b/src/main/java/org/apache/commons/proxy/exception/package.html
deleted file mode 100644
index 0216aab..0000000
--- a/src/main/java/org/apache/commons/proxy/exception/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- ~ 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.
- -->
-<html>
-<body>
-<p>
- This package contains the exception classes used by the primary API.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/factory/cglib/package.html b/src/main/java/org/apache/commons/proxy/factory/cglib/package.html
deleted file mode 100644
index e0a406c..0000000
--- a/src/main/java/org/apache/commons/proxy/factory/cglib/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ 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.
- -->
-<html>
-<body>
-<p>
- This package contains the <a href="http://cglib.sourceforge.net/">CGLIB</a>-based
- <a href="../../ProxyFactory.html">ProxyFactory</a> implementation.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/factory/javassist/package.html b/src/main/java/org/apache/commons/proxy/factory/javassist/package.html
deleted file mode 100644
index c8e64ee..0000000
--- a/src/main/java/org/apache/commons/proxy/factory/javassist/package.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains the <a href="http://www.jboss.org/products/javassist">Javassist</a>-based
- <a href="../../ProxyFactory.html">ProxyFactory</a> implementation.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/factory/util/MethodSignature.java b/src/main/java/org/apache/commons/proxy/factory/util/MethodSignature.java
deleted file mode 100644
index fabd415..0000000
--- a/src/main/java/org/apache/commons/proxy/factory/util/MethodSignature.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.proxy.factory.util;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A class for capturing the signature of a method (its name and parameter types).
- *
- * @author James Carman
- * @since 1.0
- */
-public class MethodSignature
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final String name;
- private final List parameterTypes;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public MethodSignature( Method method )
- {
- this.name = method.getName();
- this.parameterTypes = Arrays.asList(method.getParameterTypes());
- }
-
-//**********************************************************************************************************************
-// Canonical Methods
-//**********************************************************************************************************************
-
- public boolean equals( Object o )
- {
- if( this == o )
- {
- return true;
- }
- if( o == null || getClass() != o.getClass() )
- {
- return false;
- }
- final MethodSignature that = ( MethodSignature ) o;
- if( !name.equals(that.name) )
- {
- return false;
- }
- if( !parameterTypes.equals(that.parameterTypes) )
- {
- return false;
- }
- return true;
- }
-
- public int hashCode()
- {
- int result;
- result = name.hashCode();
- result = 29 * result + parameterTypes.hashCode();
- return result;
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/factory/util/package.html b/src/main/java/org/apache/commons/proxy/factory/util/package.html
deleted file mode 100644
index 0fea8e8..0000000
--- a/src/main/java/org/apache/commons/proxy/factory/util/package.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains some classes useful for writing your own <a href="../../ProxyFactory.html">ProxyFactory</a>
- implementation.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/ExecutorInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/ExecutorInterceptor.java
deleted file mode 100644
index 0608ea3..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/ExecutorInterceptor.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import EDU.oswego.cs.dl.util.concurrent.Executor;
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-
-/**
- * A method interceptor that uses an {@link Executor} to execute the method invocation.
- * <p/>
- * <b>Note</b>: Only <em>void</em> methods can be intercepted using this class! Any attempts to intercept non-void
- * methods will result in an {@link IllegalArgumentException}. If the proxy interfaces include non-void methods, try
- * using a {@link FilteredInterceptor} along with a
- * {@link org.apache.commons.proxy.interceptor.filter.ReturnTypeFilter} to wrap an instance of this class.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>Concurrent API version 1.3.4 or greater</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class ExecutorInterceptor implements Interceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Executor executor;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ExecutorInterceptor( Executor executor )
- {
- this.executor = executor;
- }
-
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
-
- public Object intercept( final Invocation invocation ) throws Throwable
- {
- if( Void.TYPE.equals(invocation.getMethod().getReturnType()) )
- {
- // Special case for finalize() method (should not be run in a different thread)...
- if( !( invocation.getMethod().getName().equals("finalize") &&
- invocation.getMethod().getParameterTypes().length == 0 ) )
- {
- executor.execute(new Runnable()
- {
- public void run()
- {
- try
- {
- invocation.proceed();
- }
- catch( Throwable t )
- {
- // What to do here? I can't convey the failure back to the caller.
- }
- }
- });
- return null;
- }
- else
- {
- return invocation.proceed();
- }
- }
- else
- {
- throw new IllegalArgumentException("Only void methods can be executed in a different thread.");
- }
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/FilteredInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/FilteredInterceptor.java
deleted file mode 100644
index 2479c69..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/FilteredInterceptor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-
-/**
- * Decorates another <code>MethodInterceptor</code> by only calling it if the method is accepted by the supplied
- * <code>MethodFilter</code>.
- *
- * @author James Carman
- * @since 1.0
- */
-public class FilteredInterceptor implements Interceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Interceptor inner;
- private final MethodFilter filter;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public FilteredInterceptor( Interceptor inner, MethodFilter filter )
- {
- this.inner = inner;
- this.filter = filter;
- }
-
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
- public Object intercept( Invocation invocation ) throws Throwable
- {
- if( filter.accepts(invocation.getMethod()) )
- {
- return inner.intercept(invocation);
- }
- else
- {
- return invocation.proceed();
- }
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/InterceptorChain.java b/src/main/java/org/apache/commons/proxy/interceptor/InterceptorChain.java
deleted file mode 100644
index b9437df..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/InterceptorChain.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.ProxyUtils;
-
-/**
- * An <code>InterceptorChain</code> assists with creating proxies which go through a series of
- * {@link Interceptor interceptors}.
- * <p/>
- * <pre>
- * MyServiceInterface serviceImpl = ...;
- * ProxyFactory factory = ...;
- * Interceptor[] interceptors = ...;
- * InterceptorChain chain = new InterceptorChain(interceptors);
- * ObjectProvider provider = chain.createProxyProvider(factory, serviceImpl);
- * MyServiceInterface serviceProxy = ( MyServiceInterface )provider.getObject();
- * serviceProxy.someServiceMethod(...); // This will go through the interceptors!
- * </pre>
- *
- * @author James Carman
- * @since 1.0
- */
-public class InterceptorChain
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Interceptor[] interceptors;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public InterceptorChain( Interceptor[] interceptors )
- {
- this.interceptors = interceptors;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Object createProxy( ProxyFactory proxyFactory, ClassLoader classLoader, Object terminus,
- Class[] proxyClasses )
- {
- Object currentTarget = terminus;
- for( int i = interceptors.length - 1; i >= 0; --i )
- {
- currentTarget = proxyFactory
- .createInterceptorProxy(classLoader, currentTarget, interceptors[i], proxyClasses);
- }
- return currentTarget;
- }
-
- /**
- * Creates an {@link ObjectProvider} which will return a proxy that sends method invocations through this
- * chain of interceptors and ultimately arrive at the supplied terminus object. The proxy will support all
- * interfaces implemented by the terminus object. The thread context classloader will be used to generate the
- * proxy class.
- *
- * @param proxyFactory the {@link ProxyFactory} to use to create the proxy
- * @param terminus the terminus
- * @return an {@link ObjectProvider} which will return a proxy that sends method invocations through this
- * chain of interceptors and ultimately arrive at the supplied terminus object
- */
- public ObjectProvider createProxyProvider( ProxyFactory proxyFactory, Object terminus )
- {
- return createProxyProvider(proxyFactory, terminus, null);
- }
-
- /**
- * Creates an {@link ObjectProvider} which will return a proxy that sends method invocations through this
- * chain of interceptors and ultimately arrive at the supplied terminus object. The proxy will support only
- * the specified interfaces/classes. The thread context classloader will be used to generate the
- * proxy class.
- *
- * @param proxyFactory the {@link ProxyFactory} to use to create the proxy
- * @param terminus the terminus
- * @param proxyClasses the interfaces to support
- * @return an {@link ObjectProvider} which will return a proxy that sends method invocations through this
- * chain of interceptors and ultimately arrive at the supplied terminus object
- */
- public ObjectProvider createProxyProvider( ProxyFactory proxyFactory, Object terminus, Class[] proxyClasses )
- {
- return createProxyProvider(proxyFactory, Thread.currentThread().getContextClassLoader(), terminus,
- proxyClasses);
- }
-
- /**
- * Creates an {@link ObjectProvider} which will return a proxy that sends method invocations through this
- * chain of interceptors and ultimately arrive at the supplied terminus object. The proxy will support only
- * the specified interfaces/classes. The specified classloader will be used to generate the
- * proxy class.
- *
- * @param proxyFactory the {@link ProxyFactory} to use to create the proxy
- * @param classLoader the classloader to be used to generate the proxy class
- * @param terminus the terminus
- * @param proxyClasses the interfaces to support
- * @return an {@link ObjectProvider} which will return a proxy that sends method invocations through this
- * chain of interceptors and ultimately arrive at the supplied terminus object
- */
- public ObjectProvider createProxyProvider( ProxyFactory proxyFactory, ClassLoader classLoader, Object terminus,
- Class[] proxyClasses )
- {
- if( proxyClasses == null || proxyClasses.length == 0 )
- {
- proxyClasses = ProxyUtils.getAllInterfaces(terminus.getClass());
- }
- return new ProxyObjectProvider(proxyFactory, classLoader, terminus, proxyClasses);
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private class ProxyObjectProvider implements ObjectProvider
- {
- private final ClassLoader classLoader;
- private final Class[] proxyClasses;
- private final Object terminus;
- private final ProxyFactory proxyFactory;
-
- public ProxyObjectProvider( ProxyFactory proxyFactory, ClassLoader classLoader, Object terminus,
- Class[] proxyClasses )
- {
- this.classLoader = classLoader;
- this.proxyClasses = proxyClasses;
- this.terminus = terminus;
- this.proxyFactory = proxyFactory;
- }
-
- public Object getObject()
- {
- return createProxy(proxyFactory, classLoader, terminus, proxyClasses);
- }
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/LoggingInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/LoggingInterceptor.java
deleted file mode 100644
index c448f96..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/LoggingInterceptor.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-import org.apache.commons.proxy.ProxyUtils;
-
-/**
- * An interceptor which logs each method invocation.
- * <b>Note</b>: The implementation of this class was borrowed from
- * HiveMind's logging interceptor.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>Apache Commons Logging version 1.0.4 or greater</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- * @deprecated please use {@link org.apache.commons.proxy.interceptor.logging.CommonsLoggingInterceptor} instead
- */
-public class LoggingInterceptor implements Interceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static final int BUFFER_SIZE = 100;
- private Log log;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public LoggingInterceptor( Log log )
- {
- this.log = log;
- }
-
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
- public Object intercept( Invocation invocation ) throws Throwable
- {
- if( log.isDebugEnabled() )
- {
- final String methodName = invocation.getMethod().getName();
- entry(methodName, invocation.getArguments());
- try
- {
- Object result = invocation.proceed();
- if( Void.TYPE.equals(invocation.getMethod().getReturnType()) )
- {
- voidExit(methodName);
- }
- else
- {
- exit(methodName, result);
- }
- return result;
- }
- catch( Throwable t )
- {
- exception(methodName, t);
- throw t;
- }
- }
- else
- {
- return invocation.proceed();
- }
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private void convert( StringBuffer buffer, Object input )
- {
- if( input == null )
- {
- buffer.append("<null>");
- return;
- }
-
- // Primitive types, and non-object arrays
- // use toString(). Less than ideal for int[], etc., but
- // that's a lot of work for a rare case.
- if( !( input instanceof Object[] ) )
- {
- buffer.append(input.toString());
- return;
- }
- buffer.append("(");
- buffer.append(ProxyUtils.getJavaClassName(input.getClass()));
- buffer.append("){");
- Object[] array = ( Object[] ) input;
- int count = array.length;
- for( int i = 0; i < count; i++ )
- {
- if( i > 0 )
- {
- buffer.append(", ");
- }
-
- // We use convert() again, because it could be a multi-dimensional array
- // (god help us) where each element must be converted.
- convert(buffer, array[i]);
- }
- buffer.append("}");
- }
-
- private void entry( String methodName, Object[] args )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("BEGIN ");
- buffer.append(methodName);
- buffer.append("(");
- int count = args.length;
- for( int i = 0; i < count; i++ )
- {
- Object arg = args[i];
- if( i > 0 )
- {
- buffer.append(", ");
- }
- convert(buffer, arg);
- }
- buffer.append(")");
- log.debug(buffer.toString());
- }
-
- private void exception( String methodName, Throwable t )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("EXCEPTION ");
- buffer.append(methodName);
- buffer.append("() -- ");
- buffer.append(t.getClass().getName());
- log.debug(buffer.toString(), t);
- }
-
- private void exit( String methodName, Object result )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("END ");
- buffer.append(methodName);
- buffer.append("() [");
- convert(buffer, result);
- buffer.append("]");
- log.debug(buffer.toString());
- }
-
- private void voidExit( String methodName )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("END ");
- buffer.append(methodName);
- buffer.append("()");
- log.debug(buffer.toString());
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/MethodFilter.java b/src/main/java/org/apache/commons/proxy/interceptor/MethodFilter.java
deleted file mode 100644
index db0c80d..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/MethodFilter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import java.lang.reflect.Method;
-import java.io.Serializable;
-
-/**
- * A <code>MethodFilter</code> determines whether or not a method is accepted.
- *
- * @author James Carman
- * @since 1.0
- */
-public interface MethodFilter extends Serializable
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- /**
- * Returns whether or not this filter accepts this method.
- *
- * @param method the method
- * @return whether or not this filter accepts this method
- */
- public boolean accepts( Method method );
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/MethodInterceptorAdapter.java b/src/main/java/org/apache/commons/proxy/interceptor/MethodInterceptorAdapter.java
deleted file mode 100644
index 09ad3ba..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/MethodInterceptorAdapter.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Method;
-
-/**
- * An adapter class to adapt AOP Alliance's {@link MethodInterceptor} interface to Commons Proxy's
- * {@link Interceptor} interface.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>AOP Alliance API version 1.0 or greater</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class MethodInterceptorAdapter implements Interceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final MethodInterceptor methodInterceptor;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public MethodInterceptorAdapter( MethodInterceptor methodInterceptor )
- {
- this.methodInterceptor = methodInterceptor;
- }
-
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
-
- public Object intercept( Invocation invocation ) throws Throwable
- {
- return methodInterceptor.invoke(new MethodInvocationAdapter(invocation));
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class MethodInvocationAdapter implements MethodInvocation
- {
- private final Invocation invocation;
-
- public MethodInvocationAdapter( Invocation invocation )
- {
- this.invocation = invocation;
- }
-
- public Method getMethod()
- {
- return invocation.getMethod();
- }
-
- public Object[] getArguments()
- {
- return invocation.getArguments();
- }
-
- public Object proceed() throws Throwable
- {
- return invocation.proceed();
- }
-
- public Object getThis()
- {
- return invocation.getProxy();
- }
-
- public AccessibleObject getStaticPart()
- {
- return invocation.getMethod();
- }
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/SerializingInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/SerializingInterceptor.java
deleted file mode 100644
index 8dc3025..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/SerializingInterceptor.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-/**
- * An interceptor which makes a serialized copy of all parameters and return values. This
- * is useful when testing remote services to ensure that all parameter/return types
- * are in fact serializable/deserializable.
- *
- * @since 1.0
- */
-public class SerializingInterceptor implements Interceptor, Serializable
-{
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
- public Object intercept( Invocation invocation ) throws Throwable
- {
- Object[] arguments = invocation.getArguments();
- for( int i = 0; i < arguments.length; i++ )
- {
- arguments[i] = serializedCopy(arguments[i]);
- }
- return serializedCopy(invocation.proceed());
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Object serializedCopy( Object original )
- {
- try
- {
- final ByteArrayOutputStream bout = new ByteArrayOutputStream();
- final ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(original);
- oout.close();
- bout.close();
- final ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
- final ObjectInputStream oin = new ObjectInputStream(bin);
- final Object copy = oin.readObject();
- oin.close();
- bin.close();
- return copy;
- }
- catch( IOException e )
- {
- throw new RuntimeException("Unable to make serialized copy of " +
- original.getClass().getName() + " object.", e);
- }
- catch( ClassNotFoundException e )
- {
- throw new RuntimeException("Unable to make serialized copy of " +
- original.getClass().getName() + " object.", e);
- }
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/filter/PatternFilter.java b/src/main/java/org/apache/commons/proxy/interceptor/filter/PatternFilter.java
deleted file mode 100644
index a926b0b..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/filter/PatternFilter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.proxy.interceptor.filter;
-
-import org.apache.commons.proxy.interceptor.MethodFilter;
-
-import java.lang.reflect.Method;
-
-/**
- * A method filter implementation that returns true if the method's name matches a supplied regular expression (JDK
- * regex) pattern string.
- *
- * @author James Carman
- * @since 1.0
- */
-public class PatternFilter implements MethodFilter
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- public static String GETTER_SETTER_PATTERN = "get\\w+|set\\w+";
- private final String pattern;
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- /**
- * Returns a {@link MethodFilter} which accepts only "getters" and "setters."
- *
- * @return a {@link MethodFilter} which accepts only "getters" and "setters."
- */
- public static MethodFilter getterSetterFilter()
- {
- return new PatternFilter(GETTER_SETTER_PATTERN);
- }
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public PatternFilter( String pattern )
- {
- this.pattern = pattern;
- }
-
-//**********************************************************************************************************************
-// MethodFilter Implementation
-//**********************************************************************************************************************
-
- public boolean accepts( Method method )
- {
- return method.getName().matches(pattern);
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/filter/ReturnTypeFilter.java b/src/main/java/org/apache/commons/proxy/interceptor/filter/ReturnTypeFilter.java
deleted file mode 100644
index bfae910..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/filter/ReturnTypeFilter.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.proxy.interceptor.filter;
-
-import org.apache.commons.proxy.interceptor.MethodFilter;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Filters methods based on their return type.
- *
- * @author James Carman
- * @since 1.0
- */
-public class ReturnTypeFilter implements MethodFilter
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Set validReturnTypes = new HashSet();
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ReturnTypeFilter( Class[] validReturnTypes )
- {
- this(Arrays.asList(validReturnTypes));
- }
-
- public ReturnTypeFilter( Collection validReturnTypes )
- {
- this.validReturnTypes.addAll(validReturnTypes);
- }
-
-//**********************************************************************************************************************
-// MethodFilter Implementation
-//**********************************************************************************************************************
-
-
- public boolean accepts( Method method )
- {
- return validReturnTypes.contains(method.getReturnType());
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/filter/SimpleFilter.java b/src/main/java/org/apache/commons/proxy/interceptor/filter/SimpleFilter.java
deleted file mode 100644
index 4f9f08a..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/filter/SimpleFilter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.proxy.interceptor.filter;
-
-import org.apache.commons.proxy.interceptor.MethodFilter;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A simple method filter implementation that merely returns true if the method's name is in a set of accepted names.
- *
- * @author James Carman
- * @since 1.0
- */
-public class SimpleFilter implements MethodFilter
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Set methodNames;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- /**
- * Creates a simple filter that accepts no methods.
- */
- public SimpleFilter()
- {
- this.methodNames = new HashSet();
- }
-
- /**
- * Creates a simple filter that accepts methods matching the supplied names.
- *
- * @param methodNames the names
- */
- public SimpleFilter( String[] methodNames )
- {
- this.methodNames = new HashSet(Arrays.asList(methodNames));
- }
-
-//**********************************************************************************************************************
-// MethodFilter Implementation
-//**********************************************************************************************************************
-
- public boolean accepts( Method method )
- {
- return methodNames.contains(method.getName());
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/filter/package.html b/src/main/java/org/apache/commons/proxy/interceptor/filter/package.html
deleted file mode 100644
index 97e6fdc..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/filter/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains some useful <a href="../MethodFilter.html">MethodFilter</a> implementations.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/logging/AbstractLoggingInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/logging/AbstractLoggingInterceptor.java
deleted file mode 100644
index 72fd527..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/logging/AbstractLoggingInterceptor.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.proxy.interceptor.logging;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-import org.apache.commons.proxy.ProxyUtils;
-
-import java.lang.reflect.Method;
-
-/**
- * @author James Carman
- * @since 1.1
- */
-public abstract class AbstractLoggingInterceptor implements Interceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static final int BUFFER_SIZE = 100;
-
-//**********************************************************************************************************************
-// Abstract Methods
-//**********************************************************************************************************************
-
- protected abstract boolean isLoggingEnabled();
-
- protected abstract void logMessage( String message );
-
- protected abstract void logMessage( String message, Throwable t );
-
-//**********************************************************************************************************************
-// Interceptor Implementation
-//**********************************************************************************************************************
-
- public Object intercept( Invocation invocation ) throws Throwable
- {
- if( isLoggingEnabled() )
- {
- final Method method = invocation.getMethod();
- entering(method, invocation.getArguments());
- try
- {
- Object result = invocation.proceed();
- exiting(method, result);
- return result;
- }
- catch( Throwable t )
- {
- throwing(method, t);
- throw t;
- }
- }
- else
- {
- return invocation.proceed();
- }
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- protected void entering( Method method, Object[] args )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("BEGIN ");
- buffer.append(method.getName());
- buffer.append("(");
- int count = args.length;
- for( int i = 0; i < count; i++ )
- {
- Object arg = args[i];
- if( i > 0 )
- {
- buffer.append(", ");
- }
- convert(buffer, arg);
- }
- buffer.append(")");
- logMessage(buffer.toString());
- }
-
- protected void convert( StringBuffer buffer, Object input )
- {
- if( input == null )
- {
- buffer.append("<null>");
- return;
- }
-
- // Primitive types, and non-object arrays
- // use toString(). Less than ideal for int[], etc., but
- // that's a lot of work for a rare case.
- if( !( input instanceof Object[] ) )
- {
- buffer.append(input.toString());
- return;
- }
- buffer.append("(");
- buffer.append(ProxyUtils.getJavaClassName(input.getClass()));
- buffer.append("){");
- Object[] array = ( Object[] ) input;
- int count = array.length;
- for( int i = 0; i < count; i++ )
- {
- if( i > 0 )
- {
- buffer.append(", ");
- }
-
- // We use convert() again, because it could be a multi-dimensional array
- // (god help us) where each element must be converted.
- convert(buffer, array[i]);
- }
- buffer.append("}");
- }
-
- protected void exiting( Method method, Object result )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("END ");
- buffer.append(method.getName());
- buffer.append("()");
- if( !Void.TYPE.equals(method.getReturnType()) )
- {
- buffer.append(" [");
- convert(buffer, result);
- buffer.append("]");
- }
- logMessage(buffer.toString());
- }
-
- protected void throwing( Method method, Throwable t )
- {
- StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
- buffer.append("EXCEPTION ");
- buffer.append(method);
- buffer.append("() -- ");
- buffer.append(t.getClass().getName());
- logMessage(buffer.toString(), t);
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/logging/CommonsLoggingInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/logging/CommonsLoggingInterceptor.java
deleted file mode 100644
index 4a6f8d4..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/logging/CommonsLoggingInterceptor.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.proxy.interceptor.logging;
-
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.logging.Log;
-
-/**
- * An interceptor which logs method invocations using an <a href="http://commons.apache.org/logging">Apache Commons
- * Logging</a> {@link Log} object at the "trace" level.
- *
- * @author James Carman
- * @since 1.1
- */
-public class CommonsLoggingInterceptor extends AbstractLoggingInterceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final String logName;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public CommonsLoggingInterceptor( String logName )
- {
- this.logName = logName;
- }
-
- public CommonsLoggingInterceptor(Class clazz)
- {
- this(clazz.getName());
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Log getLog()
- {
- return LogFactory.getLog(logName);
- }
-
- protected boolean isLoggingEnabled()
- {
- return getLog().isTraceEnabled();
- }
-
- protected void logMessage( String message )
- {
- getLog().trace(message);
- }
-
- protected void logMessage( String message, Throwable t )
- {
- getLog().trace(message, t);
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/logging/JdkLoggingInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/logging/JdkLoggingInterceptor.java
deleted file mode 100644
index a36ef27..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/logging/JdkLoggingInterceptor.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.proxy.interceptor.logging;
-
-import java.lang.reflect.Method;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * An interceptor which logs method invocations using a {@link Logger JDK logger} using the "finer" logging level.
- *
- * @author James Carman
- * @since 1.1
- */
-public class JdkLoggingInterceptor extends AbstractLoggingInterceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final String loggerName;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public JdkLoggingInterceptor( Class clazz )
- {
- this(clazz.getName());
- }
-
- public JdkLoggingInterceptor( String loggerName )
- {
- this.loggerName = loggerName;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Logger getLogger()
- {
- return Logger.getLogger(loggerName);
- }
-
- protected void entering( Method method, Object[] args )
- {
- getLogger().entering(method.getDeclaringClass().getName(), method.getName(), args);
- }
-
- protected void exiting( Method method, Object result )
- {
- getLogger().exiting(method.getDeclaringClass().getName(), method.getName(), result);
- }
-
- protected boolean isLoggingEnabled()
- {
- return getLogger().isLoggable(Level.FINER);
- }
-
- protected void logMessage( String message )
- {
- // Do nothing!
- }
-
- protected void logMessage( String message, Throwable t )
- {
- // Do nothing!
- }
-
- protected void throwing( Method method, Throwable t )
- {
- getLogger().throwing(method.getDeclaringClass().getName(), method.getName(), t);
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/logging/Slf4jInterceptor.java b/src/main/java/org/apache/commons/proxy/interceptor/logging/Slf4jInterceptor.java
deleted file mode 100644
index 2510f1d..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/logging/Slf4jInterceptor.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.proxy.interceptor.logging;
-
-import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-
-/**
- * An interceptor which logs method invocations using an <a href="http://www.slf4j.org/">SLF4J</a> {@link Logger} at the
- * "trace" logging level.
- *
- * @author James Carman
- * @since 1.1
- */
-public class Slf4jInterceptor extends AbstractLoggingInterceptor
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final String loggerName;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public Slf4jInterceptor( Class clazz )
- {
- this(clazz.getName());
- }
-
- public Slf4jInterceptor( String loggerName )
- {
- this.loggerName = loggerName;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Logger getLogger()
- {
- return LoggerFactory.getLogger(loggerName);
- }
-
- protected boolean isLoggingEnabled()
- {
- return getLogger().isTraceEnabled();
- }
-
- protected void logMessage( String message )
- {
- getLogger().debug(message);
- }
-
- protected void logMessage( String message, Throwable t )
- {
- getLogger().debug(message, t);
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/interceptor/package.html b/src/main/java/org/apache/commons/proxy/interceptor/package.html
deleted file mode 100644
index 2d4df26..0000000
--- a/src/main/java/org/apache/commons/proxy/interceptor/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains some useful <a href="../Interceptor.html">Interceptor</a> implementations.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java b/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java
deleted file mode 100644
index 25f92e1..0000000
--- a/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.ProxyUtils;
-
-import java.lang.reflect.Method;
-
-/**
- * A chain invoker will invoke the method on each object in the chain until one of them
- * returns a non-default value
- *
- * @author James Carman
- * @since 1.1
- */
-public class ChainInvoker implements Invoker
-{
- private final Object[] targets;
-
- public ChainInvoker(Object[] targets)
- {
- this.targets = targets;
- }
-
- public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable
- {
- for (int i = 0; i < targets.length; i++)
- {
- Object target = targets[i];
- Object value = method.invoke(target, arguments);
- if (value != null && !value.equals(ProxyUtils.getDefaultValue(method.getReturnType())))
- {
- return value;
- }
- }
- return ProxyUtils.getDefaultValue(method.getReturnType());
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/invoker/XmlRpcInvoker.java b/src/main/java/org/apache/commons/proxy/invoker/XmlRpcInvoker.java
deleted file mode 100644
index a9c8f2d..0000000
--- a/src/main/java/org/apache/commons/proxy/invoker/XmlRpcInvoker.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.exception.InvokerException;
-import org.apache.xmlrpc.XmlRpcException;
-import org.apache.xmlrpc.XmlRpcHandler;
-
-import java.lang.reflect.Method;
-import java.util.Vector;
-
-/**
- * Uses <a href="http://ws.apache.org/xmlrpc/">Apache XML-RPC</a> to invoke methods on an XML-RPC service.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>Apache XML-RPC version 2.0 or greater</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class XmlRpcInvoker implements Invoker
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final XmlRpcHandler handler;
- private final String handlerName;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public XmlRpcInvoker( XmlRpcHandler handler, String handlerName )
- {
- this.handler = handler;
- this.handlerName = handlerName;
- }
-
-//**********************************************************************************************************************
-// Invoker Implementation
-//**********************************************************************************************************************
-
-
- public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
- {
- final Object returnValue = handler.execute(handlerName + "." + method.getName(), toArgumentVector(args));
- if( returnValue instanceof XmlRpcException )
- {
- throw new InvokerException("Unable to execute XML-RPC call.", ( XmlRpcException ) returnValue);
- }
- return returnValue;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Vector toArgumentVector( Object[] args )
- {
- final Vector v = new Vector();
- for( int i = 0; i < args.length; i++ )
- {
- Object arg = args[i];
- v.addElement(arg);
- }
- return v;
- }
-}
diff --git a/src/main/java/org/apache/commons/proxy/invoker/package.html b/src/main/java/org/apache/commons/proxy/invoker/package.html
deleted file mode 100644
index 63de2f5..0000000
--- a/src/main/java/org/apache/commons/proxy/invoker/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains some useful <a href="../Invoker.html">Invoker</a> implementations.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/package.html b/src/main/java/org/apache/commons/proxy/package.html
deleted file mode 100644
index 98a831a..0000000
--- a/src/main/java/org/apache/commons/proxy/package.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<body>
-<p>
- This package contains the primary API.
-</p>
-</body>
\ No newline at end of file
diff --git a/src/main/java/org/apache/commons/proxy/provider/ConstantProvider.java b/src/main/java/org/apache/commons/proxy/provider/ConstantProvider.java
deleted file mode 100644
index 8645848..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/ConstantProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.proxy.provider;
-
-import org.apache.commons.proxy.ObjectProvider;
-
-import java.io.Serializable;
-
-/**
- * Always returns the same object.
- *
- * @author James Carman
- * @since 1.0
- */
-public class ConstantProvider implements ObjectProvider, Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final Object constant;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ConstantProvider( Object constant )
- {
- this.constant = constant;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- return constant;
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/ProviderDecorator.java b/src/main/java/org/apache/commons/proxy/provider/ProviderDecorator.java
deleted file mode 100644
index 251ece8..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/ProviderDecorator.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.proxy.provider;
-
-import org.apache.commons.proxy.ObjectProvider;
-
-/**
- * Returns the result of the inner {@link ObjectProvider provider}. Subclasses can override the {@link #getObject()}
- * method and decorate what comes back from the inner provider in some way (by {@link SingletonProvider caching it} for
- * example).
- *
- * @author James Carman
- * @since 1.0
- */
-public class ProviderDecorator implements ObjectProvider
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- protected ObjectProvider inner;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public ProviderDecorator( ObjectProvider inner )
- {
- this.inner = inner;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- return inner.getObject();
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/package.html b/src/main/java/org/apache/commons/proxy/provider/package.html
deleted file mode 100644
index c5a0977..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains some general-use <a href="../ObjectProvider.html">ObjectProvider</a> implementations.
-</p>
-</body>
-</html>
diff --git a/src/main/java/org/apache/commons/proxy/provider/remoting/BurlapProvider.java b/src/main/java/org/apache/commons/proxy/provider/remoting/BurlapProvider.java
deleted file mode 100644
index 6aac5b8..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/remoting/BurlapProvider.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import com.caucho.burlap.client.BurlapProxyFactory;
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import java.io.Serializable;
-import java.net.MalformedURLException;
-
-/**
- * Provides a burlap service object.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>Burlap version 2.1.7 or greater</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class BurlapProvider implements ObjectProvider, Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private Class serviceInterface;
- private String url;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public BurlapProvider()
- {
- }
-
- public BurlapProvider( Class serviceInterface, String url )
- {
- this.serviceInterface = serviceInterface;
- this.url = url;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- try
- {
- return new BurlapProxyFactory().create(serviceInterface, url);
- }
- catch( MalformedURLException e )
- {
- throw new ObjectProviderException("Invalid url given.", e);
- }
- }
-
-//**********************************************************************************************************************
-// Getter/Setter Methods
-//**********************************************************************************************************************
-
- public void setServiceInterface( Class serviceInterface )
- {
- this.serviceInterface = serviceInterface;
- }
-
- public void setUrl( String url )
- {
- this.url = url;
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/remoting/HessianProvider.java b/src/main/java/org/apache/commons/proxy/provider/remoting/HessianProvider.java
deleted file mode 100644
index aacf244..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/remoting/HessianProvider.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import com.caucho.hessian.client.HessianProxyFactory;
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import java.io.Serializable;
-import java.net.MalformedURLException;
-
-/**
- * Provides a hessian service object.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>Hessian version 3.0.1 or greater</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class HessianProvider implements ObjectProvider, Serializable
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private Class serviceInterface;
- private String url;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public HessianProvider()
- {
- }
-
- public HessianProvider( Class serviceInterface, String url )
- {
- this.serviceInterface = serviceInterface;
- this.url = url;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- try
- {
- return new HessianProxyFactory().create(serviceInterface, url);
- }
- catch( MalformedURLException e )
- {
- throw new ObjectProviderException("Invalid url given.", e);
- }
- }
-
-//**********************************************************************************************************************
-// Getter/Setter Methods
-//**********************************************************************************************************************
-
- public void setServiceInterface( Class serviceInterface )
- {
- this.serviceInterface = serviceInterface;
- }
-
- public void setUrl( String url )
- {
- this.url = url;
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/remoting/JaxRpcProvider.java b/src/main/java/org/apache/commons/proxy/provider/remoting/JaxRpcProvider.java
deleted file mode 100644
index 15ce7b1..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/remoting/JaxRpcProvider.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import javax.xml.namespace.QName;
-import javax.xml.rpc.Service;
-import javax.xml.rpc.ServiceException;
-import javax.xml.rpc.ServiceFactory;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Returns a proxy for a JAX-RPC-based service.
- * <p/>
- * <p>
- * <b>Dependencies</b>:
- * <ul>
- * <li>A JAX-RPC implementation</li>
- * </ul>
- * </p>
- *
- * @author James Carman
- * @since 1.0
- */
-public class JaxRpcProvider implements ObjectProvider
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private Class serviceInterface;
- private String wsdlUrl;
- private String serviceNamespaceUri;
- private String serviceLocalPart;
- private String servicePrefix;
- private String portNamespaceUri;
- private String portLocalPart;
- private String portPrefix;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public JaxRpcProvider()
- {
- }
-
- public JaxRpcProvider( Class serviceInterface )
- {
- this.serviceInterface = serviceInterface;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- try
- {
- final Service service = ( wsdlUrl == null ?
- ServiceFactory.newInstance().createService(getServiceQName()) : ServiceFactory
- .newInstance().createService(new URL(wsdlUrl), getServiceQName()) );
- final QName portQName = getPortQName();
- return portQName == null ? service.getPort(serviceInterface) :
- service.getPort(portQName, serviceInterface);
- }
- catch( ServiceException e )
- {
- throw new ObjectProviderException("Unable to create JAX-RPC service proxy.", e);
- }
- catch( MalformedURLException e )
- {
- throw new ObjectProviderException("Invalid URL given.", e);
- }
- }
-
-//**********************************************************************************************************************
-// Getter/Setter Methods
-//**********************************************************************************************************************
-
- public void setPortLocalPart( String portLocalPart )
- {
- this.portLocalPart = portLocalPart;
- }
-
- public void setPortNamespaceUri( String portNamespaceUri )
- {
- this.portNamespaceUri = portNamespaceUri;
- }
-
- public void setPortPrefix( String portPrefix )
- {
- this.portPrefix = portPrefix;
- }
-
- public void setServiceInterface( Class serviceInterface )
- {
- this.serviceInterface = serviceInterface;
- }
-
- public void setServiceLocalPart( String serviceLocalPart )
- {
- this.serviceLocalPart = serviceLocalPart;
- }
-
- public void setServiceNamespaceUri( String serviceNamespaceUri )
- {
- this.serviceNamespaceUri = serviceNamespaceUri;
- }
-
- public void setServicePrefix( String servicePrefix )
- {
- this.servicePrefix = servicePrefix;
- }
-
- public void setWsdlUrl( String wsdlUrl )
- {
- this.wsdlUrl = wsdlUrl;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private QName getPortQName()
- {
- return getQName(portNamespaceUri, portLocalPart, portPrefix);
- }
-
- private QName getQName( String namespaceUri, String localPart, String prefix )
- {
- if( namespaceUri != null && localPart != null && prefix != null )
- {
- return new QName(namespaceUri, localPart, prefix);
- }
- else if( namespaceUri != null && localPart != null )
- {
- return new QName(namespaceUri, localPart);
- }
- else if( localPart != null )
- {
- return new QName(localPart);
- }
- return null;
- }
-
- private QName getServiceQName()
- {
- return getQName(serviceNamespaceUri, serviceLocalPart, servicePrefix);
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/remoting/RmiProvider.java b/src/main/java/org/apache/commons/proxy/provider/remoting/RmiProvider.java
deleted file mode 100644
index 1dd7edf..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/remoting/RmiProvider.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import java.rmi.NotBoundException;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMIClientSocketFactory;
-
-/**
- * Provides an object by looking it up in an RMI registry.
- *
- * @author James Carman
- * @since 1.0
- */
-public class RmiProvider implements ObjectProvider
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private String host = "localhost";
- private int port = Registry.REGISTRY_PORT;
- private RMIClientSocketFactory clientSocketFactory;
- private String name;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public RmiProvider()
- {
- }
-
- public RmiProvider( String name )
- {
- setName(name);
- }
-
- public RmiProvider( String host, String name )
- {
- setHost(host);
- setName(name);
- }
-
- public RmiProvider( String host, int port, String name )
- {
- setHost(host);
- setName(name);
- setPort(port);
- }
-
- public RmiProvider( String host, int port, RMIClientSocketFactory clientSocketFactory, String name )
- {
- setHost(host);
- setPort(port);
- setClientSocketFactory(clientSocketFactory);
- setName(name);
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- Registry reg = null;
- try
- {
- reg = getRegistry();
- return reg.lookup(name);
- }
- catch( NotBoundException e )
- {
- throw new ObjectProviderException("Name " + name + " not found in registry at " + host + ":" + port + ".",
- e);
- }
- catch( RemoteException e )
- {
- throw new ObjectProviderException(
- "Unable to lookup service named " + name + " in registry at " + host + ":" + port + ".", e);
- }
- }
-
-//**********************************************************************************************************************
-// Getter/Setter Methods
-//**********************************************************************************************************************
-
- public void setClientSocketFactory( RMIClientSocketFactory clientSocketFactory )
- {
- this.clientSocketFactory = clientSocketFactory;
- }
-
- public void setHost( String host )
- {
- this.host = host;
- }
-
- public void setName( String name )
- {
- this.name = name;
- }
-
- public void setPort( int port )
- {
- this.port = port;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private Registry getRegistry()
- {
- try
- {
- if( clientSocketFactory != null )
- {
- return LocateRegistry.getRegistry(host, port, clientSocketFactory);
- }
- else
- {
- return LocateRegistry.getRegistry(host, port);
- }
- }
- catch( RemoteException e )
- {
- throw new ObjectProviderException("Unable to locate registry at " + host + ":" + port + ".", e);
- }
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/remoting/SessionBeanProvider.java b/src/main/java/org/apache/commons/proxy/provider/remoting/SessionBeanProvider.java
deleted file mode 100644
index 4499f0a..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/remoting/SessionBeanProvider.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.ProxyUtils;
-import org.apache.commons.proxy.exception.ObjectProviderException;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.rmi.PortableRemoteObject;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Properties;
-
-/**
- * Provides a reference to a session bean by looking up the home object and calling (via reflection) the no-argument
- * create() method. This will work for both local and remote session beans.
- *
- * @author James Carman
- * @since 1.0
- */
-public class SessionBeanProvider implements ObjectProvider
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private final String jndiName;
- private final Class homeInterface;
- private final Properties properties;
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public SessionBeanProvider( String jndiName, Class homeInterface )
- {
- this.jndiName = jndiName;
- this.homeInterface = homeInterface;
- this.properties = null;
- }
-
- public SessionBeanProvider( String jndiName, Class homeInterface, Properties properties )
- {
- this.jndiName = jndiName;
- this.homeInterface = homeInterface;
- this.properties = properties;
- }
-
-//**********************************************************************************************************************
-// ObjectProvider Implementation
-//**********************************************************************************************************************
-
- public Object getObject()
- {
- try
- {
- final InitialContext initialContext = properties == null ? new InitialContext() :
- new InitialContext(properties);
- Object homeObject = PortableRemoteObject.narrow(initialContext.lookup(jndiName), homeInterface);
- final Method createMethod = homeObject.getClass().getMethod("create", ProxyUtils.EMPTY_ARGUMENT_TYPES);
- return createMethod.invoke(homeObject, ProxyUtils.EMPTY_ARGUMENTS);
- }
- catch( NoSuchMethodException e )
- {
- throw new ObjectProviderException(
- "Unable to find no-arg create() method on home interface " + homeInterface.getName() + ".", e);
- }
- catch( IllegalAccessException e )
- {
- throw new ObjectProviderException(
- "No-arg create() method on home interface " + homeInterface.getName() + " is not accessible.",
- e); // Should never happen!
- }
- catch( NamingException e )
- {
- throw new ObjectProviderException("Unable to lookup EJB home object in JNDI.", e);
- }
- catch( InvocationTargetException e )
- {
- throw new ObjectProviderException(
- "No-arg create() method on home interface " + homeInterface.getName() + " threw an exception.", e);
- }
- }
-}
-
diff --git a/src/main/java/org/apache/commons/proxy/provider/remoting/package.html b/src/main/java/org/apache/commons/proxy/provider/remoting/package.html
deleted file mode 100644
index e906038..0000000
--- a/src/main/java/org/apache/commons/proxy/provider/remoting/package.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- ~ 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.
- -->
-
-<html>
-<body>
-<p>
- This package contains some useful <a href="../../ObjectProvider.html">ObjectProvider</a> implementations for use
- in remoting situations (EJB, RMI, Burlap, Hessian, JAX-RPC, etc).
-</p>
-</body>
-</html>
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
new file mode 100644
index 0000000..040dfe7
--- /dev/null
+++ b/src/site/markdown/index.md
@@ -0,0 +1,145 @@
+<!--
+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.
+-->
+
+## Commons Proxy: Dynamic Proxies Made Easy
+
+ The *Proxy* design pattern ([GoF][]) allows you to provide
+ "a surrogate or placeholder for another object to control access to it".
+ Proxies can be used in many ways, some of which are:
+
+ * **Deferred Initialization** -
+ the proxy acts as a "stand-in" for the actual implementation allowing
+ it to be instantiated only when absolutely necessary.
+ * **Security** -
+ the proxy object can verify that the user actually has the permission to
+ execute the method (a la EJB).
+ * **Logging** -
+ the proxy can log evey method invocation, providing valuable debugging
+ information.
+ * **Performance Monitoring** -
+ the proxy can log each method invocation to a performance monitor allowing
+ system administrators to see what parts of the system are potentially
+ bogged down.
+
+ *Commons Proxy* supports dynamic proxy generation using proxy factories,
+ object providers, invokers, and interceptors.
+
+## Proxy Factories
+ A [ProxyFactory][] encapsulates all necessary proxying logic away from your
+ code. Switching proxying techniques/technologies is as simple as using a
+ different proxy factory implementation class.
+ *Commons Proxy* provides several proxy factory implementation modules:
+
+ * [commons-proxy2-jdk][]
+ * [commons-proxy2-cglib][]
+ * [commons-proxy2-javassist][]
+ * [commons-proxy2-asm4][]
+
+ Additionally, the core library provides a proxy factory
+ [implementation][defaultPF] that delegates to instances discoverable using
+ the Java [ServiceLoader][] mechanism (including those provided by the listed
+ modules).
+
+ Proxy factories allow you to create three different types of proxy objects:
+
+ * **Delegator Proxy** - delegates each method invocation to an object
+ provided by an [ObjectProvider][].
+ * **Interceptor Proxy** - allows an [Interceptor][] to intercept each
+ method invocation as it makes its way to the target of the invocation.
+ * **Invoker Proxy** - uses an [Invoker][] to handle all method invocations.
+
+## Object Providers
+ [Object providers][providers] provide the objects which will be the
+ "target" of a proxy. There are two types of object providers:
+
+### Core Object Providers
+ A core object provider provides a core implementation object.
+ *Commons Proxy* supports many different implementations including:
+
+ * **Constant** - Always returns a specific object
+ * **Bean** - Instantiates an object of a specified class each time
+ * **Cloning** - Reflectively calls the public `clone()` method
+ on a `Cloneable` object
+
+### Decorating Object Providers
+ A decorating object provider decorates the object returned by another
+ provider. *Commons Proxy* provides a few implementations including:
+
+ * **Singleton** - Calls a nested provider at most once, returning that
+ original value on all subsequent invocations
+
+## Invokers
+ An [Invoker][] handles all method invocations using a single method.
+ *Commons Proxy* provides a few invoker implementations:
+
+ * **Null** - Always returns a `null` (useful for the "Null Object" pattern)
+ * **Duck Typing** - Supports so-called "duck typing" by adapting a class to
+ an interface it does not implement.
+ * **Invocation Handler Adapter** - Adapts an implementation of the JDK
+[InvocationHandler][] interface as a *Commons Proxy* [Invoker][].
+
+## Interceptors
+ *Commons Proxy* allows you to "intercept" a method invocation using
+ an [Interceptor][]. Interceptors provide *rudimentary* aspect-oriented
+ programming (AOP) support, allowing you to alter the parameters/results
+ of a method invocation without actually changing the implementation of
+ the method itself. *Commons Proxy* provides a few interceptor
+ implementations including:
+
+ * **ObjectProvider** - returns the value from an [ObjectProvider][]
+ * **Throwing** - throws an exception
+ * **Switch** - provides a fluent API to configure the handling
+ of invoked methods
+
+## Releases
+ The latest version is v1.0. - [Download now!][download]
+
+ For previous releases, see the [Apache archive][archive].
+
+ _**Note:** The 1.x releases are compatible with JDK1.4+._
+
+## Support
+ The [Commons mailing lists][mailing-lists] act as the main support forum.
+ The `user` list is suitable for most library usage queries.
+ The `dev` list is intended for the development discussion.
+ Please remember that the lists are shared between all Commons components,
+ so prefix your email subject with `[proxy]`.
+
+ Issues may be reported via [ASF JIRA][issue-tracking]. Please read the
+ instructions carefully to submit a useful bug report or enhancement request.
+
+[download]: http://commons.apache.org/downloads/download_proxy.cgi
+[archive]: http://archive.apache.org/dist/commons/proxy/
+[mailing-lists]: mail-lists.html
+[issue-tracking]: issue-tracking.html
+
+[commons-proxy2-jdk]: commons-proxy2-jdk/index.html
+[commons-proxy2-cglib]: commons-proxy2-cglib/index.html
+[commons-proxy2-javassist]: commons-proxy2-javassist/index.html
+[commons-proxy2-asm4]: commons-proxy2-asm4/index.html
+[ProxyFactory]: apidocs/org/apache/commons/proxy2/ProxyFactory.html
+[ObjectProvider]: apidocs/org/apache/commons/proxy2/ObjectProvider.html
+[Interceptor]: apidocs/org/apache/commons/proxy2/Interceptor.html
+[Invoker]: apidocs/org/apache/commons/proxy2/Invoker.html
+[defaultPF]: apidocs/org/apache/commons/proxy2/ProxyUtils.html#proxyFactory\(\)
+[providers]: apidocs/org/apache/commons/proxy2/provider/package-summary.html
+
+[ServiceLoader]: http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
+[InvocationHandler]: http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/InvocationHandler.html
+[GoF]: http://www.amazon.com/exec/obidos/tg/detail/-/0201633612/qid=1125413337/sr=1-1/ref=sr_1_1/104-0714405-6441551?v=glance&s=books
diff --git a/src/site/resources/download_proxy.cgi b/src/site/resources/download_proxy.cgi
deleted file mode 100644
index 495cde1..0000000
--- a/src/site/resources/download_proxy.cgi
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-# Just call the standard mirrors.cgi script. It will use download.html
-# as the input template.
-exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $*
\ No newline at end of file
diff --git a/src/site/site.xml b/src/site/site.xml
index 13ce200..143f2f3 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
+
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
@@ -15,6 +16,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
+
<project name="Commons Proxy">
<bannerRight>
<name>Commons Proxy</name>
@@ -24,7 +26,6 @@
<body>
<menu name="Commons Proxy">
<item name="Overview" href="index.html"/>
- <item name="Download" href="http://commons.apache.org/proxy/download_proxy.cgi"/>
<item name="Mailing lists" href="/mail-lists.html"/>
<item name="Issue Tracking" href="/issue-tracking.html"/>
<item name="Team" href="/team-list.html"/>
diff --git a/src/site/xdoc/download_proxy.xml b/src/site/xdoc/download_proxy.xml
index 2ac93b4..41af3db 100644
--- a/src/site/xdoc/download_proxy.xml
+++ b/src/site/xdoc/download_proxy.xml
@@ -1,20 +1,21 @@
<?xml version="1.0"?>
<!--
-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
+ ~ 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.
+ -->
- 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.
--->
<!--
+======================================================================+
|**** ****|
@@ -50,7 +51,6 @@
</properties>
<body>
<section name="Download Commons Proxy">
- <subsection name="Using a Mirror">
<p>
We recommend you use a mirror to download our release
builds, but you <strong>must</strong> verify the integrity of
@@ -88,51 +88,59 @@
</form>
<p>
- The <a href="http://www.apache.org/dist/commons/KEYS">KEYS</a>
- link links to the code signing keys used to sign the product.
+ The <code>KEYS</code> link links to the code signing keys used to sign the product.
The <code>PGP</code> link downloads the OpenPGP compatible signature from our main site.
The <code>MD5</code> link downloads the checksum from the main site.
</p>
- </subsection>
- </section>
- <section name="Commons Proxy 1.0 ">
- <subsection name="Binaries">
- <table>
- <tr>
- <td><a href="[preferred]/commons/proxy/binaries/commons-proxy-1.0.tar.gz">commons-proxy-1.0.tar.gz</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.tar.gz.md5">md5</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.tar.gz.asc">pgp</a></td>
- </tr>
- <tr>
- <td><a href="[preferred]/commons/proxy/binaries/commons-proxy-1.0.zip">commons-proxy-1.0.zip</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.zip.md5">md5</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.zip.asc">pgp</a></td>
- </tr>
- </table>
- </subsection>
- <subsection name="Source">
- <table>
- <tr>
- <td><a href="[preferred]/commons/proxy/source/commons-proxy-1.0-src.tar.gz">commons-proxy-1.0-src.tar.gz</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.tar.gz.md5">md5</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.tar.gz.asc">pgp</a></td>
- </tr>
- <tr>
- <td><a href="[preferred]/commons/proxy/source/commons-proxy-1.0-src.zip">commons-proxy-1.0-src.zip</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.zip.md5">md5</a></td>
- <td><a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.zip.asc">pgp</a></td>
- </tr>
- </table>
- </subsection>
- </section>
- <section name="Archives">
- <p>
- Older releases can be obtained from the archives.
- </p>
- <ul>
+
+ <p>
+ For more information concerning Commons Proxy, see the
+ <a href="index.html" class="name">Commons Proxy</a> web site.
+ </p>
+
+ <p>
+ <div class="links"><span class="link"><a href="http://www.apache.org/dist/commons/KEYS">KEYS</a></span></div>
+ <ul class="downloads">
+ <li class="group"><div class="links"><span class="label">Binary</span></div>
+ <ul>
+ <li class="download"><a href="[preferred]/commons/proxy/binaries/commons-proxy-1.0.tar.gz">1.0.tar.gz</a>
+ <ul class="attributes">
+ <li><span class="md5">[<a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.tar.gz.md5">md5</a>]</span>
+ <span class="pgp">[<a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.tar.gz.asc">pgp</a>]</span>
+ </li>
+ </ul>
+ </li>
+ <li class="download"><a href="[preferred]/commons/proxy/binaries/commons-proxy-1.0.zip">1.0.zip</a>
+ <ul class="attributes">
+ <li><span class="md5">[<a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.zip.md5">md5</a>]</span>
+ <span class="pgp">[<a href="http://www.apache.org/dist/commons/proxy/binaries/commons-proxy-1.0.zip.asc">pgp</a>]</span>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li class="group"><div class="links"><span class="label">Source</span></div>
+ <ul>
+ <li class="download"><a href="[preferred]/commons/proxy/source/commons-proxy-1.0-src.tar.gz">1.0.tar.gz</a>
+ <ul class="attributes">
+ <li><span class="md5">[<a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.tar.gz.md5">md5</a>]</span>
+ <span class="pgp">[<a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.tar.gz.asc">pgp</a>]</span>
+ </li>
+ </ul>
+ </li>
+ <li class="download"><a href="[preferred]/commons/proxy/source/commons-proxy-1.0-src.zip">1.0.zip</a>
+ <ul class="attributes">
+ <li><span class="md5">[<a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.zip.md5">md5</a>]</span>
+ <span class="pgp">[<a href="http://www.apache.org/dist/commons/proxy/source/commons-proxy-1.0-src.zip.asc">pgp</a>]</span>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
<li class="download"><a href="[preferred]/commons/proxy/">browse download area</a></li>
<li><a href="http://archive.apache.org/dist/commons/proxy/">archives...</a></li>
</ul>
+ </p>
</section>
</body>
</document>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
deleted file mode 100644
index 4e4d0a4..0000000
--- a/src/site/xdoc/index.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0"?>
-<!--
- ~ 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.
- -->
-<document>
- <properties>
- <title>Overview</title>
- <author email="dev AT commons DOT apache DOT org">Apache Commons Development Team</author>
- <author email="jcarman AT apache DOT org">James Carman</author>
- </properties>
-
- <body>
- <section name="Commons Proxy: Dynamic Proxies Made Easy">
- <p>
- The <em>Proxy</em> design pattern (<a href="http://www.amazon.com/exec/obidos/tg/detail/-/0201633612/qid=1125413337/sr=1-1/ref=sr_1_1/104-0714405-6441551?v=glance&s=books">GoF</a>)
- allows you to provide "a surrogate or placeholder for another object to control access to it".
- Proxies can be used in many ways. Some of which are:
- </p>
- <ul>
- <li><b>Deferred Initialization</b> - the proxy acts as a "stand-in" for the actual implementation allowing
- it to be instantiated only when absolutely necessary.</li>
- <li><b>Security</b> - the proxy object can verify that the user actually has the permission to execute
- the method (a la EJB).</li>
- <li><b>Logging</b> - the proxy can log evey method invocation, providing valuable debugging information.</li>
- <li><b>Performance Monitoring</b> - the proxy can log each method invocation to a performance monitor
- allowing system administrators to see what parts of the system are potentially bogged down.</li>
- </ul>
- <p>
- <em>Commons Proxy</em> supports dynamic proxy generation using proxy factories, object providers, invokers, and
- interceptors.
- </p>
- <section name="Proxy Factories">
- <p>
- <a href="apidocs/org/apache/commons/proxy/ProxyFactory.html">Proxy factories</a>
- encapsulate all necessary proxying logic away from your code. Switching proxying
- techniques/technologies is as simple as using a different proxy factory implementation class.
- Currently, <em>Commons Proxy</em> provides proxy factory implementations using JDK proxies,
- <a href="http://cglib.sourceforge.net">CGLIB</a>, and
- <a href="http://www.jboss.org/products/javassist">Javassist</a>. Proxy factories allow you to create
- three different types of proxy objects:
- </p>
- <ul>
- <li><b>Delegator Proxies</b> - a proxy that merely delegates each method invocation to an
- object provided by an <a href="apidocs/org/apache/commons/proxy/ObjectProvider.html">object provider</a>.</li>
- <li><b>Interceptor Proxies</b> - a proxy that allows an <a href="apidocs/org/apache/commons/proxy/Interceptor.html">Interceptor</a> to intercept each
- method invocation as it makes its way to the target of the invocation.</li>
- <li><b>Invoker Proxies</b> - a proxy that uses an
- <a href="apidocs/org/apache/commons/proxy/Invoker.html">invoker</a> to handle all method
- invocations.</li>
- </ul>
- </section>
- <section name="Object Providers">
- <p>
- <a href="apidocs/org/apache/commons/proxy/provider/package-summary.html">Object providers</a>
- provide the
- objects which will be the "target" of a proxy. There are two types of object providers:
- <subsection name="Core Object Providers">
- <p>
- A core object provider provides a core implementation object. <em>Commons Proxy</em> supports
- many different implementations including:
- </p>
- <table border="0">
- <tr><td><b>Constant</b></td><td>Always returns a specific object</td></tr>
- <tr><td><b>Bean</b></td><td>Merely instantiates an object of a specified class each time</td></tr>
- <tr><td><b>Cloning</b></td><td>Reflectively calls the public clone() method on a Cloneable object</td></tr>
- <tr><td><b>Hessian</b></td><td>Returns a <a href="http://www.caucho.com/hessian/index.xtp">Hessian</a>-based service object</td></tr>
- <tr><td><b>Burlap</b></td><td>Returns a <a href="http://www.caucho.com/burlap/index.xtp">Burlap</a>-based service object</td></tr>
- <tr><td><b>JAX-RPC</b></td><td>Returns a <a href="http://java.sun.com/webservices/jaxrpc/index.jsp">JAX-RPC</a>-based service object</td></tr>
- <tr><td><b>Session Bean</b></td><td>Returns a reference to a Session EJB (stateless session beans only)</td></tr>
- </table>
- </subsection>
- <subsection name="Decorating Object Providers">
- <p>
- A decorating object provider decorates the object returned by another provider.
- <em>Commons Proxy</em> provides a few implementations including:
- </p>
- <table border="0">
- <tr><td><b>Singleton</b></td><td>Calls a nested provider at most once, returning that original value on all subsequent invocations</td></tr>
- </table>
-
- </subsection>
-
- </p>
- </section>
- <section name="Invokers">
- <p>
- An <a href="apidocs/org/apache/commons/proxy/Invoker.html">invoker</a> handles all
- method invocations using a single method. <em>Commons Proxy</em> provides a few invoker implementations:
- </p>
- <table border="0">
- <tr><td><b>Null</b></td><td>Always returns a null (useful for the "Null Object" pattern)</td></tr>
- <tr><td><b>Apache XML-RPC</b></td><td>Uses <a href="http://ws.apache.org/xmlrpc/">Apache XML-RPC</a> to fulfill the method invocation</td></tr>
- <tr><td><b>Duck Typing</b></td><td>Supports "duck typing" by adapting a class to an interface it does not implement.</td></tr>
- <tr><td><b>Invocation Handler Adapter</b></td><td>Adapts the JDK <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/InvocationHandler.html">InvocationHandler</a> interface
- to the <em>Commons Proxy</em> <a href="apidocs/org/apache/commons/proxy/Invoker.html">Invoker</a> interface.</td></tr>
- </table>
-
- </section>
- <section name="Interceptors">
- <p>
- <em>Commons Proxy</em> allows you to "intercept" a method invocation using <a href="apidocs/org/apache/commons/proxy/Interceptor.html">Interceptors</a>.
- Interceptors provide <em>rudimentary</em> aspect-oriented
- programming support, allowing you to alter the results/effects of a method invocation without actually
- changing the implementation of the method itself. <em>Commons Proxy</em> provides a few interceptor
- implementations including:
- </p>
- <table border="0">
- <tr><td><b>Executor</b></td><td>Uses an
- <a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/Executor.html">Executor</a> to execute the method in possibly another thread (only void methods are supported).</td></tr>
- <tr><td><b>Logging</b></td><td>Logs all method invocations using the
- <a href="http://commons.apache.org/logging/">Apache Commons Logging</a> API</td></tr>
- <tr><td><b>Filtered</b></td><td>Optionally intercepts a method invocation based on a
- <a href="apidocs/org/apache/commons/proxy/interceptor/MethodFilter.html">method filter</a></td></tr>
- <tr><td><b>Method Interceptor Adapter</b></td><td>Adapts the AOP Alliance <a href="http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html">MethodInterceptor</a> interface to the
- <em>Commons Proxy</em> <a href="apidocs/org/apache/commons/proxy/Interceptor.html">Interceptor</a> interface.</td></tr>
-
- </table>
- </section>
- </section>
- <section name="Releases">
- <p>
- The latest version is v1.0. -
- <a href="http://commons.apache.org/proxy/download_proxy.cgi">Download now!</a><br />
- </p>
- <p>
- For previous releases, see the <a href="http://archive.apache.org/dist/commons/proxy/">Apache Archive</a>
- </p>
- <p>
- <i><b>Note:</b> The 1.x releases are compatible with JDK1.4+.</i>
- </p>
- </section>
- <section name="Support">
- <p>
- The <a href="mail-lists.html">commons mailing lists</a> act as the main support forum.
- The user list is suitable for most library usage queries.
- The dev list is intended for the development discussion.
- Please remember that the lists are shared between all commons components,
- so prefix your email subject with [proxy].
- </p>
- <p>
- Issues may be reported via <a href="issue-tracking.html">ASF JIRA</a>.
- Please read the instructions carefully to submit a useful bug report or enhancement request.
- </p>
- </section>
- </body>
-</document>
diff --git a/src/site/xdoc/issue-tracking.xml b/src/site/xdoc/issue-tracking.xml
index b55530c..985210a 100644
--- a/src/site/xdoc/issue-tracking.xml
+++ b/src/site/xdoc/issue-tracking.xml
@@ -1,20 +1,21 @@
<?xml version="1.0"?>
<!--
-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
+ ~ 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.
+ -->
- 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.
--->
<!--
+======================================================================+
|**** ****|
diff --git a/src/site/xdoc/mail-lists.xml b/src/site/xdoc/mail-lists.xml
deleted file mode 100644
index e0f628d..0000000
--- a/src/site/xdoc/mail-lists.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-<?xml version="1.0"?>
-<!--
-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.
--->
-<!--
- +======================================================================+
- |**** ****|
- |**** THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN ****|
- |**** DO NOT EDIT DIRECTLY ****|
- |**** ****|
- +======================================================================+
- | TEMPLATE FILE: mail-lists-template.xml |
- | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
- +======================================================================+
- | |
- | 1) Re-generate using: mvn commons:mail-page |
- | |
- | 2) Set the following properties in the component's pom: |
- | - commons.componentid (required, alphabetic, lower case) |
- | |
- | 3) Example Properties |
- | |
- | <properties> |
- | <commons.componentid>math</commons.componentid> |
- | </properties> |
- | |
- +======================================================================+
--->
-<document>
- <properties>
- <title>Commons Proxy Mailing Lists</title>
- <author email="dev@commons.apache.org">Commons Documentation Team</author>
- </properties>
- <body>
-
- <section name="Overview">
- <p>
- <a href="index.html">Commons Proxy</a> shares mailing lists with all the other
- <a href="http://commons.apache.org/components.html">Commons Components</a>.
- To make it easier for people to only read messages related to components they are interested in,
- the convention in Commons is to prefix the subject line of messages with the component's name,
- for example:
- <ul>
- <li>[proxy] Problem with the ...</li>
- </ul>
- </p>
- <p>
- Questions related to the usage of Commons Proxy should be posted to the
- <a href="http://mail-archives.apache.org/mod_mbox/commons-user/">User List</a>.
- <br />
- The <a href="http://mail-archives.apache.org/mod_mbox/commons-dev/">Developer List</a>
- is for questions and discussion related to the development of Commons Proxy.
- <br />
- Please do not cross-post; developers are also subscribed to the user list.
- </p>
- <p>
- <strong>Note:</strong> please don't send patches or attachments to any of the mailing lists.
- Patches are best handled via the <a href="issue-tracking.html">Issue Tracking</a> system.
- Otherwise, please upload the file to a public server and include the URL in the mail.
- </p>
- </section>
-
- <section name="Commons Proxy Mailing Lists">
- <p>
- <strong>Please prefix the subject line of any messages for <a href="index.html">Commons Proxy</a>
- with <i>[proxy]</i></strong> - <i>thanks!</i>
- <br />
- <br />
- </p>
-
- <table>
- <tr>
- <th>Name</th>
- <th>Subscribe</th>
- <th>Unsubscribe</th>
- <th>Post</th>
- <th>Archive</th>
- <th>Other Archives</th>
- </tr>
-
-
- <tr>
- <td>
- <strong>Commons User List</strong>
- <br /><br />
- Questions on using Commons Proxy.
- <br /><br />
- </td>
- <td><a href="mailto:user-subscribe@commons.apache.org">Subscribe</a></td>
- <td><a href="mailto:user-unsubscribe@commons.apache.org">Unsubscribe</a></td>
- <td><a href="mailto:user@commons.apache.org?subject=[proxy]">Post</a></td>
- <td><a href="http://mail-archives.apache.org/mod_mbox/commons-user/">mail-archives.apache.org</a></td>
- <td><a href="http://markmail.org/list/org.apache.commons.users/">markmail.org</a><br />
- <a href="http://www.mail-archive.com/user@commons.apache.org/">www.mail-archive.com</a><br />
- <a href="http://news.gmane.org/gmane.comp.jakarta.commons.devel">news.gmane.org</a>
- </td>
- </tr>
-
-
- <tr>
- <td>
- <strong>Commons Developer List</strong>
- <br /><br />
- Discussion of development of Commons Proxy.
- <br /><br />
- </td>
- <td><a href="mailto:dev-subscribe@commons.apache.org">Subscribe</a></td>
- <td><a href="mailto:dev-unsubscribe@commons.apache.org">Unsubscribe</a></td>
- <td><a href="mailto:dev@commons.apache.org?subject=[proxy]">Post</a></td>
- <td><a href="http://mail-archives.apache.org/mod_mbox/commons-dev/">mail-archives.apache.org</a></td>
- <td><a href="http://markmail.org/list/org.apache.commons.dev/">markmail.org</a><br />
- <a href="http://www.mail-archive.com/dev@commons.apache.org/">www.mail-archive.com</a><br />
- <a href="http://news.gmane.org/gmane.comp.jakarta.commons.devel">news.gmane.org</a>
- </td>
- </tr>
-
-
- <tr>
- <td>
- <strong>Commons Issues List</strong>
- <br /><br />
- Only for e-mails automatically generated by the <a href="issue-tracking.html">issue tracking</a> system.
- <br /><br />
- </td>
- <td><a href="mailto:issues-subscribe@commons.apache.org">Subscribe</a></td>
- <td><a href="mailto:issues-unsubscribe@commons.apache.org">Unsubscribe</a></td>
- <td><i>read only</i></td>
- <td><a href="http://mail-archives.apache.org/mod_mbox/commons-issues/">mail-archives.apache.org</a></td>
- <td><a href="http://markmail.org/list/org.apache.commons.issues/">markmail.org</a><br />
- <a href="http://www.mail-archive.com/issues@commons.apache.org/">www.mail-archive.com</a>
- </td>
- </tr>
-
-
- <tr>
- <td>
- <strong>Commons Commits List</strong>
- <br /><br />
- Only for e-mails automatically generated by the <a href="source-repository.html">source control</a> sytem.
- <br /><br />
- </td>
- <td><a href="mailto:commits-subscribe@commons.apache.org">Subscribe</a></td>
- <td><a href="mailto:commits-unsubscribe@commons.apache.org">Unsubscribe</a></td>
- <td><i>read only</i></td>
- <td><a href="http://mail-archives.apache.org/mod_mbox/commons-commits/">mail-archives.apache.org</a></td>
- <td><a href="http://markmail.org/list/org.apache.commons.commits/">markmail.org</a><br />
- <a href="http://www.mail-archive.com/commits@commons.apache.org/">www.mail-archive.com</a>
- </td>
- </tr>
-
- </table>
-
- </section>
- <section name="Apache Mailing Lists">
- <p>
- Other mailing lists which you may find useful include:
- </p>
-
- <table>
- <tr>
- <th>Name</th>
- <th>Subscribe</th>
- <th>Unsubscribe</th>
- <th>Post</th>
- <th>Archive</th>
- <th>Other Archives</th>
- </tr>
- <tr>
- <td>
- <strong>Apache Announce List</strong>
- <br /><br />
- General announcements of Apache project releases.
- <br /><br />
- </td>
- <td><a class="externalLink" href="mailto:announce-subscribe@apache.org">Subscribe</a></td>
- <td><a class="externalLink" href="mailto:announce-unsubscribe@apache.org">Unsubscribe</a></td>
- <td><i>read only</i></td>
- <td><a class="externalLink" href="http://mail-archives.apache.org/mod_mbox/www-announce/">mail-archives.apache.org</a></td>
- <td><a class="externalLink" href="http://markmail.org/list/org.apache.announce/">markmail.org</a><br />
- <a class="externalLink" href="http://old.nabble.com/Apache-News-and-Announce-f109.html">old.nabble.com</a><br />
- <a class="externalLink" href="http://www.mail-archive.com/announce@apache.org/">www.mail-archive.com</a><br />
- <a class="externalLink" href="http://news.gmane.org/gmane.comp.apache.announce">news.gmane.org</a>
- </td>
- </tr>
- </table>
-
- </section>
- </body>
-</document>
diff --git a/src/test/java/org/apache/commons/proxy/TestProxyFactory.java b/src/test/java/org/apache/commons/proxy/TestProxyFactory.java
deleted file mode 100644
index adcb216..0000000
--- a/src/test/java/org/apache/commons/proxy/TestProxyFactory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.proxy;
-
-import org.apache.commons.proxy.factory.AbstractProxyFactoryTestCase;
-
-public class TestProxyFactory extends AbstractProxyFactoryTestCase
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public TestProxyFactory()
- {
- super(new ProxyFactory());
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/factory/AbstractProxyFactoryTestCase.java b/src/test/java/org/apache/commons/proxy/factory/AbstractProxyFactoryTestCase.java
deleted file mode 100644
index f9e74d7..0000000
--- a/src/test/java/org/apache/commons/proxy/factory/AbstractProxyFactoryTestCase.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * 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.proxy.factory;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.Invocation;
-import org.apache.commons.proxy.Invoker;
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.provider.BeanProvider;
-import org.apache.commons.proxy.provider.ConstantProvider;
-import org.apache.commons.proxy.provider.SingletonProvider;
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.util.DuplicateEcho;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-import org.apache.commons.proxy.util.SuffixInterceptor;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.Date;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public abstract class AbstractProxyFactoryTestCase extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static final Class[] ECHO_ONLY = new Class[]{Echo.class};
- protected final ProxyFactory factory;
- private static final Class[] COMPARABLE_ONLY = new Class[] { Comparable.class };
-
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- protected AbstractProxyFactoryTestCase(ProxyFactory factory)
- {
- this.factory = factory;
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- private ObjectProvider createSingletonEcho()
- {
- return new SingletonProvider(new BeanProvider(EchoImpl.class));
- }
-
- public void testInterceptorHashCode()
- {
- final Echo proxy = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
- assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
- }
-
- public void testInvokerHashCode() throws Exception
- {
- final Echo proxy = (Echo) factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
- assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
- }
-
- public void testDelegatorHashCode() throws Exception
- {
- final Echo proxy = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), ECHO_ONLY);
- assertEquals(proxy.hashCode(), System.identityHashCode(proxy));
- }
-
-
- public void testInterceptorEquals()
- {
- final Date date = new Date();
- final Comparable proxy1 = (Comparable) factory.createInterceptorProxy(date,
- new NoOpMethodInterceptor(), COMPARABLE_ONLY);
- final Comparable proxy2 = (Comparable) factory.createInterceptorProxy(date,
- new NoOpMethodInterceptor(), COMPARABLE_ONLY);
- assertEquals(proxy1, proxy1);
- assertFalse(proxy1.equals(proxy2));
- assertFalse(proxy2.equals(proxy1));
- }
-
- public void testInvokerEquals() throws Exception
- {
- final Comparable proxy1 = (Comparable) factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
- final Comparable proxy2 = (Comparable) factory.createInvokerProxy(new InvokerTester(), COMPARABLE_ONLY);
- assertEquals(proxy1, proxy1);
- assertFalse(proxy1.equals(proxy2));
- assertFalse(proxy2.equals(proxy1));
- }
-
- public void testDelegatorEquals() throws Exception
- {
- final Date date = new Date();
- final Comparable proxy1 = (Comparable) factory.createDelegatorProxy(new ConstantProvider(date),
- COMPARABLE_ONLY);
- final Comparable proxy2 = (Comparable) factory.createDelegatorProxy(new ConstantProvider(date),
- COMPARABLE_ONLY);
- assertEquals(proxy1, proxy1);
- assertFalse(proxy1.equals(proxy2));
- assertFalse(proxy2.equals(proxy1));
- }
-
- public void testBooleanInterceptorParameter()
- {
- final Echo echo = (Echo) factory.createInterceptorProxy(new EchoImpl(), new InterceptorTester(), ECHO_ONLY);
- assertFalse(echo.echoBack(false));
- assertTrue(echo.echoBack(true));
- }
-
- public void testCanProxy()
- {
- assertTrue(factory.canProxy(ECHO_ONLY));
- assertFalse(factory.canProxy(new Class[]{EchoImpl.class}));
- }
-
- public void testChangingArguments()
- {
- final Echo proxy = (Echo) factory.createInterceptorProxy(new EchoImpl(), new ChangeArgumentInterceptor(), ECHO_ONLY);
- assertEquals("something different", proxy.echoBack("whatever"));
- }
-
- public void testCreateDelegatingProxy()
- {
- final Echo echo = (Echo) factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
- echo.echo();
- assertEquals("message", echo.echoBack("message"));
- assertEquals("ab", echo.echoBack("a", "b"));
- }
-
- public void testCreateInterceptorProxy()
- {
- final Echo target = (Echo) factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
- final Echo proxy = (Echo) factory.createInterceptorProxy(target, new SuffixInterceptor(" suffix"), ECHO_ONLY);
- proxy.echo();
- assertEquals("message suffix", proxy.echoBack("message"));
- }
-
- public void testDelegatingProxyClassCaching() throws Exception
- {
- final Echo proxy1 = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), ECHO_ONLY);
- final Echo proxy2 = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), ECHO_ONLY);
- assertNotSame(proxy1, proxy2);
- assertSame(proxy1.getClass(), proxy2.getClass());
- }
-
- public void testDelegatingProxyInterfaceOrder()
- {
- final Echo echo = (Echo) factory.createDelegatorProxy(createSingletonEcho(), new Class[]{Echo.class, DuplicateEcho.class});
- final List expected = new LinkedList(Arrays.asList(new Class[]{Echo.class, DuplicateEcho.class}));
- final List actual = new LinkedList(Arrays.asList(echo.getClass().getInterfaces()));
- actual.retainAll(expected); // Doesn't alter order!
- assertEquals(expected, actual);
- }
-
- public void testDelegatingProxySerializable() throws Exception
- {
- final Echo proxy = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), ECHO_ONLY);
- assertSerializable(proxy);
- }
-
- public void testInterceptingProxyClassCaching() throws Exception
- {
- final Echo proxy1 = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
- final Echo proxy2 = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
- assertNotSame(proxy1, proxy2);
- assertSame(proxy1.getClass(), proxy2.getClass());
- }
-
- public void testInterceptingProxySerializable() throws Exception
- {
- final Echo proxy = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
- assertSerializable(proxy);
- }
-
- public void testInterceptorProxyWithCheckedException() throws Exception
- {
- final Echo proxy = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
- try
- {
- proxy.ioException();
- fail();
- }
- catch (IOException e)
- {
- }
- }
-
- public void testInterceptorProxyWithUncheckedException() throws Exception
- {
- final Echo proxy = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), ECHO_ONLY);
- try
- {
- proxy.illegalArgument();
- fail();
- }
- catch (IllegalArgumentException e)
- {
- }
- }
-
- public void testInterfaceHierarchies()
- {
- final SortedSet set = (SortedSet) factory.createDelegatorProxy(new ConstantProvider(new TreeSet()), new Class[]{SortedSet.class});
- set.add("Hello");
- }
-
- public void testInvokerProxy() throws Exception
- {
- final InvokerTester tester = new InvokerTester();
- final Echo echo = (Echo) factory.createInvokerProxy(tester, ECHO_ONLY);
- echo.echoBack("hello");
- assertEquals(Echo.class.getMethod("echoBack", new Class[]{String.class}), tester.method);
- assertSame(echo, tester.proxy);
- assertNotNull(tester.args);
- assertEquals(1, tester.args.length);
- assertEquals("hello", tester.args[0]);
- }
-
- public void testInvokerProxyClassCaching() throws Exception
- {
- final Echo proxy1 = (Echo) factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
- final Echo proxy2 = (Echo) factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
- assertNotSame(proxy1, proxy2);
- assertSame(proxy1.getClass(), proxy2.getClass());
- }
-
- public void testInvokerProxySerializable() throws Exception
- {
- final Echo proxy = (Echo) factory.createInvokerProxy(new InvokerTester(), ECHO_ONLY);
- assertSerializable(proxy);
- }
-
- public void testMethodInvocationClassCaching() throws Exception
- {
- final InterceptorTester tester = new InterceptorTester();
- final EchoImpl target = new EchoImpl();
- final Echo proxy1 = (Echo) factory.createInterceptorProxy(target, tester, ECHO_ONLY);
- final Echo proxy2 = (Echo) factory.createInterceptorProxy(target, tester, new Class[]{Echo.class, DuplicateEcho.class});
- proxy1.echoBack("hello1");
- final Class invocationClass1 = tester.invocationClass;
- proxy2.echoBack("hello2");
- assertSame(invocationClass1, tester.invocationClass);
- }
-
- public void testMethodInvocationDuplicateMethods() throws Exception
- {
- final InterceptorTester tester = new InterceptorTester();
- final EchoImpl target = new EchoImpl();
- final Echo proxy = (Echo) factory.createInterceptorProxy(target, tester, new Class[]{Echo.class, DuplicateEcho.class});
- proxy.echoBack("hello");
- assertEquals(Echo.class.getMethod("echoBack", new Class[]{String.class}), tester.method);
- }
-
- public void testMethodInvocationImplementation() throws Exception
- {
- final InterceptorTester tester = new InterceptorTester();
- final EchoImpl target = new EchoImpl();
- final Echo proxy = (Echo) factory.createInterceptorProxy(target, tester, ECHO_ONLY);
- proxy.echo();
- assertNotNull(tester.arguments);
- assertEquals(0, tester.arguments.length);
- assertEquals(Echo.class.getMethod("echo", new Class[]{}), tester.method);
- assertEquals(target, tester.proxy);
- proxy.echoBack("Hello");
- assertNotNull(tester.arguments);
- assertEquals(1, tester.arguments.length);
- assertEquals("Hello", tester.arguments[0]);
- assertEquals(Echo.class.getMethod("echoBack", new Class[]{String.class}), tester.method);
- proxy.echoBack("Hello", "World");
- assertNotNull(tester.arguments);
- assertEquals(2, tester.arguments.length);
- assertEquals("Hello", tester.arguments[0]);
- assertEquals("World", tester.arguments[1]);
- assertEquals(Echo.class.getMethod("echoBack", new Class[]{String.class, String.class}), tester.method);
- }
-
- public void testPrimitiveParameter()
- {
- final Echo echo = (Echo) factory.createDelegatorProxy(createSingletonEcho(), ECHO_ONLY);
- assertEquals(1, echo.echoBack(1));
- }
-
- public void testProxyWithCheckedException() throws Exception
- {
- final Echo proxy = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), ECHO_ONLY);
- try
- {
- proxy.ioException();
- fail();
- }
- catch (IOException e)
- {
- }
- }
-
- public void testProxyWithUncheckedException() throws Exception
- {
- final Echo proxy = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), ECHO_ONLY);
- try
- {
- proxy.illegalArgument();
- fail();
- }
- catch (IllegalArgumentException e)
- {
- }
- }
-
- public void testWithNonAccessibleTargetType()
- {
- final Echo proxy = (Echo) factory.createInterceptorProxy(new PrivateEcho(), new NoOpMethodInterceptor(), ECHO_ONLY);
- proxy.echo();
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class ChangeArgumentInterceptor implements Interceptor
- {
- public Object intercept(Invocation methodInvocation) throws Throwable
- {
- methodInvocation.getArguments()[0] = "something different";
- return methodInvocation.proceed();
- }
- }
-
- protected static class InterceptorTester implements Interceptor
- {
- private Object[] arguments;
- private Method method;
- private Object proxy;
- private Class invocationClass;
-
- public Object intercept(Invocation methodInvocation) throws Throwable
- {
- arguments = methodInvocation.getArguments();
- method = methodInvocation.getMethod();
- proxy = methodInvocation.getProxy();
- invocationClass = methodInvocation.getClass();
- return methodInvocation.proceed();
- }
- }
-
- protected static class InvokerTester implements Invoker
- {
- private Object method;
- private Object[] args;
- private Object proxy;
-
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- this.proxy = proxy;
- this.method = method;
- this.args = args;
- return null;
- }
- }
-
- protected static class NoOpMethodInterceptor implements Interceptor, Serializable
- {
- public Object intercept(Invocation methodInvocation) throws Throwable
- {
- return methodInvocation.proceed();
- }
- }
-
- private static class PrivateEcho extends EchoImpl
- {
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java b/src/test/java/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java
deleted file mode 100644
index 9733f58..0000000
--- a/src/test/java/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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.proxy.factory;
-
-import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.exception.ProxyFactoryException;
-import org.apache.commons.proxy.invoker.NullInvoker;
-import org.apache.commons.proxy.provider.ConstantProvider;
-import org.apache.commons.proxy.util.AbstractEcho;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-
-import java.util.Date;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public abstract class AbstractSubclassingProxyFactoryTestCase extends AbstractProxyFactoryTestCase
-{
- private static final Class[] DATE_ONLY = new Class[]{Date.class};
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- protected AbstractSubclassingProxyFactoryTestCase(ProxyFactory factory)
- {
- super(factory);
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testCanProxy()
- {
- assertTrue(factory.canProxy(new Class[]{Echo.class}));
- assertTrue(factory.canProxy(new Class[]{EchoImpl.class}));
- assertFalse(factory.canProxy(new Class[]{FinalEcho.class}));
- assertTrue(factory.canProxy(new Class[]{FinalMethodEcho.class, Echo.class}));
- assertFalse(factory.canProxy(new Class[]{NoDefaultConstructorEcho.class}));
- assertTrue(factory.canProxy(new Class[]{ProtectedConstructorEcho.class}));
- assertFalse(factory.canProxy(new Class[]{InvisibleEcho.class}));
- assertFalse(factory.canProxy(new Class[]{Echo.class, EchoImpl.class, String.class}));
- }
-
- public void testDelegatorWithMultipleSuperclasses()
- {
- try
- {
- factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()),
- new Class[]{EchoImpl.class, String.class});
- fail();
- }
- catch (ProxyFactoryException e)
- {
- }
- }
-
- public void testDelegatorWithSuperclass()
- {
- final Echo echo = (Echo) factory
- .createDelegatorProxy(new ConstantProvider(new EchoImpl()), new Class[]{Echo.class, EchoImpl.class});
- assertTrue(echo instanceof EchoImpl);
- }
-
- public void testInterceptorWithMultipleSuperclasses()
- {
- try
- {
- factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(),
- new Class[]{EchoImpl.class, String.class});
- fail();
- }
- catch (ProxyFactoryException e)
- {
- }
- }
-
- public void testInterceptorWithSuperclass()
- {
- final Echo echo = (Echo) factory
- .createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[]{Echo.class, EchoImpl.class});
- assertTrue(echo instanceof EchoImpl);
- }
-
- public void testInvocationHandlerWithMultipleSuperclasses()
- {
- try
- {
- factory.createInvokerProxy(new NullInvoker(),
- new Class[]{EchoImpl.class, String.class});
- fail();
- }
- catch (ProxyFactoryException e)
- {
- }
- }
-
- public void testInvokerWithSuperclass()
- {
- final Echo echo = (Echo) factory
- .createInvokerProxy(new NullInvoker(), new Class[]{Echo.class, EchoImpl.class});
- assertTrue(echo instanceof EchoImpl);
- }
-
- public void testProxiesWithClashingFinalMethodInSuperclass()
- {
- final Class[] proxyClasses = new Class[]{Echo.class, FinalMethodEcho.class};
- Echo proxy = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), proxyClasses);
- assertEquals("final", proxy.echoBack("echo"));
-
- proxy = (Echo) factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), proxyClasses);
- assertEquals("final", proxy.echoBack("echo"));
-
- proxy = (Echo) factory.createInvokerProxy(new NullInvoker(), proxyClasses);
- assertEquals("final", proxy.echoBack("echo"));
- }
-
- public void testWithAbstractSuperclass()
- {
- final Echo echo = (Echo) factory.createDelegatorProxy(new ConstantProvider(new EchoImpl()), new Class[]{AbstractEcho.class});
- assertEquals("hello", echo.echoBack("hello"));
- assertEquals("helloworld", echo.echoBack("hello", "world"));
- }
-
- public void testInterceptorEquals()
- {
- final EqualsEcho echo = new EqualsEcho("text");
- final Echo proxy1 = (Echo) factory.createInterceptorProxy(echo,
- new NoOpMethodInterceptor(), new Class[] { EqualsEcho.class } );
- final Echo proxy2 = (Echo) factory.createInterceptorProxy(echo,
- new NoOpMethodInterceptor(), new Class[] { EqualsEcho.class } );
- assertEquals(proxy1, proxy1);
- assertFalse(proxy1.equals(proxy2));
- assertFalse(proxy2.equals(proxy1));
- }
-
- public void testInvokerEquals() throws Exception
- {
- final Date proxy1 = (Date) factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);
- final Date proxy2 = (Date) factory.createInvokerProxy(new InvokerTester(), DATE_ONLY);
- assertEquals(proxy1, proxy1);
- assertFalse(proxy1.equals(proxy2));
- assertFalse(proxy2.equals(proxy1));
- }
-
- public void testDelegatorEquals() throws Exception
- {
- final EqualsEcho echo = new EqualsEcho("text");
- final Echo proxy1 = (Echo) factory.createDelegatorProxy(new ConstantProvider(echo),
- new Class[] { EqualsEcho.class });
- final Echo proxy2 = (Echo) factory.createDelegatorProxy(new ConstantProvider(echo),
- new Class[] { EqualsEcho.class });
- assertEquals(proxy1, proxy1);
- assertFalse(proxy1.equals(proxy2));
- assertFalse(proxy2.equals(proxy1));
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- public static final class FinalEcho extends EchoImpl
- {
- }
-
- public static class FinalMethodEcho extends EchoImpl
- {
- public final String echoBack(String message)
- {
- return "final";
- }
- }
-
- public static class EqualsEcho extends EchoImpl
- {
- private final String text;
-
- public EqualsEcho()
- {
- this("testing");
- }
-
- public EqualsEcho(String text)
- {
- this.text = text;
- }
- }
-
- private static class InvisibleEcho extends EchoImpl
- {
- }
-
- public static class NoDefaultConstructorEcho extends EchoImpl
- {
- public NoDefaultConstructorEcho(String param)
- {
- }
- }
-
- public static class ProtectedConstructorEcho extends EchoImpl
- {
- protected ProtectedConstructorEcho()
- {
- }
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/factory/cglib/TestCglibProxyFactory.java b/src/test/java/org/apache/commons/proxy/factory/cglib/TestCglibProxyFactory.java
deleted file mode 100644
index 1bb2f57..0000000
--- a/src/test/java/org/apache/commons/proxy/factory/cglib/TestCglibProxyFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.proxy.factory.cglib;
-
-import org.apache.commons.proxy.factory.AbstractSubclassingProxyFactoryTestCase;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class TestCglibProxyFactory extends AbstractSubclassingProxyFactoryTestCase
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public TestCglibProxyFactory()
- {
- super(new CglibProxyFactory());
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/factory/javassist/TestJavassistProxyFactory.java b/src/test/java/org/apache/commons/proxy/factory/javassist/TestJavassistProxyFactory.java
deleted file mode 100644
index 031221f..0000000
--- a/src/test/java/org/apache/commons/proxy/factory/javassist/TestJavassistProxyFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.proxy.factory.javassist;
-
-import org.apache.commons.proxy.factory.AbstractSubclassingProxyFactoryTestCase;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class TestJavassistProxyFactory extends AbstractSubclassingProxyFactoryTestCase
-{
-//**********************************************************************************************************************
-// Constructors
-//**********************************************************************************************************************
-
- public TestJavassistProxyFactory()
- {
- super(new JavassistProxyFactory());
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/factory/util/TestMethodSignature.java b/src/test/java/org/apache/commons/proxy/factory/util/TestMethodSignature.java
deleted file mode 100644
index 30c5ea4..0000000
--- a/src/test/java/org/apache/commons/proxy/factory/util/TestMethodSignature.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.proxy.factory.util;
-
-import junit.framework.TestCase;
-import org.apache.commons.proxy.util.DuplicateEcho;
-import org.apache.commons.proxy.util.Echo;
-
-public class TestMethodSignature extends TestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testEquals() throws Exception
- {
- final MethodSignature sig = new MethodSignature(Echo.class.getMethod("echoBack", new Class[] {String.class}));
- assertTrue(sig.equals(sig));
- assertFalse(sig.equals("echoBack"));
- assertEquals(sig, new MethodSignature(Echo.class.getMethod("echoBack", new Class[] {String.class})));
- assertEquals(sig, new MethodSignature(DuplicateEcho.class.getMethod("echoBack", new Class[] {String.class})));
- assertFalse(sig.equals(new MethodSignature(Echo.class.getMethod("echoBack", new Class[] {String.class, String.class}))));
- assertFalse(sig.equals(new MethodSignature(Echo.class.getMethod("echo", new Class[] {}))));
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/TestExecutorInterceptor.java b/src/test/java/org/apache/commons/proxy/interceptor/TestExecutorInterceptor.java
deleted file mode 100644
index f927fe0..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/TestExecutorInterceptor.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import EDU.oswego.cs.dl.util.concurrent.CountDown;
-import EDU.oswego.cs.dl.util.concurrent.Executor;
-import junit.framework.TestCase;
-import org.apache.commons.proxy.factory.cglib.CglibProxyFactory;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-
-public class TestExecutorInterceptor extends TestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testMethodThrowsException()
- {
- final ExceptionEcho impl = new ExceptionEcho();
- final OneShotExecutor executor = new OneShotExecutor();
- final Echo proxy = ( Echo ) new CglibProxyFactory()
- .createInterceptorProxy(impl, new ExecutorInterceptor(executor), new Class[] {Echo.class});
- proxy.echo();
- }
-
- public void testNonVoidMethod() throws Exception
- {
- final ExecutedEcho impl = new ExecutedEcho();
- final OneShotExecutor executor = new OneShotExecutor();
- final Echo proxy = ( Echo ) new CglibProxyFactory()
- .createInterceptorProxy(impl, new ExecutorInterceptor(executor), new Class[] {Echo.class});
- try
- {
- proxy.echoBack("hello");
- fail();
- }
- catch( IllegalArgumentException e )
- {
- }
- }
-
- public void testVoidMethod() throws Exception
- {
- final ExecutedEcho impl = new ExecutedEcho();
- final OneShotExecutor executor = new OneShotExecutor();
- final Echo proxy = ( Echo ) new CglibProxyFactory()
- .createInterceptorProxy(impl, new ExecutorInterceptor(executor), new Class[] {Echo.class});
- proxy.echo();
- executor.getLatch().acquire();
- assertEquals(executor.getThread(), impl.getExecutionThread());
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
-//
-// Inner Classes
-//
- public static class ExceptionEcho extends EchoImpl
- {
- public void echo()
- {
- throw new RuntimeException("Oops!");
- }
- }
-
- public static class ExecutedEcho extends EchoImpl
- {
- private Thread executionThread;
-
- public void echo()
- {
- executionThread = Thread.currentThread();
- }
-
- public Thread getExecutionThread()
- {
- return executionThread;
- }
- }
-
- private static class OneShotExecutor implements Executor
- {
- private Thread thread;
- private CountDown latch = new CountDown(1);
-
- public void execute( final Runnable command )
- {
- thread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- command.run();
- }
- finally
- {
- latch.release();
- }
- }
- });
- thread.start();
- }
-
- public Thread getThread()
- {
- return thread;
- }
-
- public CountDown getLatch()
- {
- return latch;
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/TestFilteredInterceptor.java b/src/test/java/org/apache/commons/proxy/interceptor/TestFilteredInterceptor.java
deleted file mode 100644
index 403d19a..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/TestFilteredInterceptor.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.factory.cglib.CglibProxyFactory;
-import org.apache.commons.proxy.interceptor.filter.SimpleFilter;
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-import org.apache.commons.proxy.util.SuffixInterceptor;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class TestFilteredInterceptor extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerialization()
- {
- assertSerializable(new FilteredInterceptor(new SuffixInterceptor("a"), new SimpleFilter(new String[] {"echoBack"})));
- }
-
- public void testFilterAccepts()
- {
- Echo echo = ( Echo ) new InterceptorChain(new Interceptor[] {new FilteredInterceptor(new SuffixInterceptor("a"), new SimpleFilter(new String[] {"echoBack"}))}).createProxyProvider(new CglibProxyFactory(), new EchoImpl()).getObject();
- assertEquals("messagea", echo.echoBack("message"));
- }
-
- public void testFilterDenies()
- {
- Echo echo = ( Echo ) new InterceptorChain(new Interceptor[] {new FilteredInterceptor(new SuffixInterceptor("a"), new SimpleFilter())}).createProxyProvider(new CglibProxyFactory(), new EchoImpl()).getObject();
- assertEquals("message", echo.echoBack("message"));
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/TestInterceptorChain.java b/src/test/java/org/apache/commons/proxy/interceptor/TestInterceptorChain.java
deleted file mode 100644
index daea4db..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/TestInterceptorChain.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.proxy.Interceptor;
-import org.apache.commons.proxy.factory.cglib.CglibProxyFactory;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-import org.apache.commons.proxy.util.SuffixInterceptor;
-import org.apache.commons.proxy.util.AbstractTestCase;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class TestInterceptorChain extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerializable()
- {
- Echo echo = ( Echo ) new InterceptorChain(new Interceptor[] {new SuffixInterceptor("a"), new SuffixInterceptor("b")}).createProxyProvider(new CglibProxyFactory(), new EchoImpl(), new Class[] {Echo.class}).getObject();
- assertSerializable(echo);
- }
-
- public void testWithMultipleInterceptors()
- {
- Echo echo = ( Echo ) new InterceptorChain(new Interceptor[] {new SuffixInterceptor("a"), new SuffixInterceptor("b")}).createProxyProvider(new CglibProxyFactory(), new EchoImpl(), new Class[] {Echo.class}).getObject();
- assertEquals("messageba", echo.echoBack("message"));
- }
-
- public void testWithSingleInterceptor()
- {
- Echo echo = ( Echo ) new InterceptorChain(new Interceptor[] {new SuffixInterceptor("a")}).createProxyProvider(new CglibProxyFactory(), new EchoImpl(), new Class[] {Echo.class}).getObject();
- assertEquals("messagea", echo.echoBack("message"));
- }
-}
-
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/TestLoggingInterceptor.java b/src/test/java/org/apache/commons/proxy/interceptor/TestLoggingInterceptor.java
deleted file mode 100644
index 8b3feda..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/TestLoggingInterceptor.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.proxy.factory.cglib.CglibProxyFactory;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-import org.jmock.Mock;
-import org.jmock.MockObjectTestCase;
-
-import java.io.IOException;
-
-public class TestLoggingInterceptor extends MockObjectTestCase
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private Mock logMock;
- private Echo echo;
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- protected void setUp() throws Exception
- {
- logMock = mock(Log.class);
- echo = ( Echo ) new CglibProxyFactory()
- .createInterceptorProxy(new EchoImpl(), new LoggingInterceptor(( Log ) logMock.proxy()),
- new Class[] {Echo.class});
- }
-
- public void testException()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN ioException()"));
- logMock.expects(once()).method("debug").with(eq("EXCEPTION ioException() -- java.io.IOException"), isA(IOException.class));
- try
- {
- echo.ioException();
- fail();
- }
- catch( IOException e )
- {
- }
- }
-
- public void testMultipleParameters()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN echoBack(Hello, World)"));
- logMock.expects(once()).method("debug").with(eq("END echoBack() [HelloWorld]"));
- echo.echoBack("Hello", "World");
- }
-
- public void testNonVoidMethod()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN echoBack(Hello)"));
- logMock.expects(once()).method("debug").with(eq("END echoBack() [Hello]"));
- echo.echoBack("Hello");
- }
-
- public void testNullReturnValue()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN echoBack(<null>)"));
- logMock.expects(once()).method("debug").with(eq("END echoBack() [<null>]"));
- echo.echoBack(( String ) null);
- }
-
- public void testRuntimeException()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN illegalArgument()"));
- logMock.expects(once()).method("debug").with(eq("EXCEPTION illegalArgument() -- java.lang.IllegalArgumentException"), isA(IllegalArgumentException.class));
- try
- {
- echo.illegalArgument();
- fail();
- }
- catch( IllegalArgumentException e )
- {
- }
- }
-
- public void testVoidMethod()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN echo()"));
- logMock.expects(once()).method("debug").with(eq("END echo()"));
- echo.echo();
- }
-
- public void testWhenLoggingDisabled()
- {
- logMock = mock(Log.class);
- echo = ( Echo ) new CglibProxyFactory()
- .createInterceptorProxy(new EchoImpl(), new LoggingInterceptor(( Log ) logMock.proxy()),
- new Class[] {Echo.class});
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(false));
- echo.echoBack("Hello");
- }
-
- public void testWithArrayParameter()
- {
- logMock.expects(once()).method("isDebugEnabled").will(returnValue(true));
- logMock.expects(once()).method("debug").with(eq("BEGIN echoBack((java.lang.String[]){Hello, World})"));
- logMock.expects(once()).method("debug").with(eq("END echoBack() [HelloWorld]"));
- echo.echoBack(new String[] {"Hello", "World"});
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/TestMethodInterceptorAdapter.java b/src/test/java/org/apache/commons/proxy/interceptor/TestMethodInterceptorAdapter.java
deleted file mode 100644
index 108d376..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/TestMethodInterceptorAdapter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.proxy.factory.javassist.JavassistProxyFactory;
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-
-import java.io.Serializable;
-
-public class TestMethodInterceptorAdapter extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerialization()
- {
- final Echo proxy = ( Echo ) new JavassistProxyFactory().createInterceptorProxy(new EchoImpl(),
- new MethodInterceptorAdapter(new SuffixMethodInterceptor(
- " suffix")),
- new Class[] {Echo.class});
- assertSerializable(proxy);
- }
-
- public void testMethodInterception()
- {
- final Echo proxy = ( Echo ) new JavassistProxyFactory().createInterceptorProxy(new EchoImpl(),
- new MethodInterceptorAdapter(new SuffixMethodInterceptor(
- " suffix")),
- new Class[] {Echo.class});
- assertEquals("message suffix", proxy.echoBack("message"));
- }
-
- public void testMethodInvocationImplementation() throws Exception
- {
- final InterceptorTester tester = new InterceptorTester();
- final EchoImpl target = new EchoImpl();
- final Echo proxy = ( Echo ) new JavassistProxyFactory().createInterceptorProxy(target, new MethodInterceptorAdapter(tester), new Class[] {Echo.class});
- proxy.echo();
- assertNotNull(tester.invocation.getArguments());
- assertEquals(0, tester.invocation.getArguments().length);
- assertEquals(Echo.class.getMethod("echo", new Class[] {}), tester.invocation.getMethod());
- assertEquals(Echo.class.getMethod("echo", new Class[] {}), tester.invocation.getStaticPart());
- assertEquals(target, tester.invocation.getThis());
- proxy.echoBack("Hello");
- assertNotNull(tester.invocation.getArguments());
- assertEquals(1, tester.invocation.getArguments().length);
- assertEquals("Hello", tester.invocation.getArguments()[0]);
- assertEquals(Echo.class.getMethod("echoBack", new Class[] {String.class}), tester.invocation.getMethod());
- assertEquals(Echo.class.getMethod("echoBack", new Class[] {String.class}), tester.invocation.getStaticPart());
- proxy.echoBack("Hello", "World");
- assertNotNull(tester.invocation.getArguments());
- assertEquals(2, tester.invocation.getArguments().length);
- assertEquals("Hello", tester.invocation.getArguments()[0]);
- assertEquals("World", tester.invocation.getArguments()[1]);
- assertEquals(Echo.class.getMethod("echoBack", new Class[] {String.class, String.class}), tester.invocation.getMethod());
- assertEquals(Echo.class.getMethod("echoBack", new Class[] {String.class, String.class}), tester.invocation.getStaticPart());
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class InterceptorTester implements MethodInterceptor
- {
- private MethodInvocation invocation;
-
- public Object invoke( MethodInvocation methodInvocation ) throws Throwable
- {
- this.invocation = methodInvocation;
- return methodInvocation.proceed();
- }
- }
-
- private static class SuffixMethodInterceptor implements MethodInterceptor, Serializable
- {
- private final String suffix;
-
- public SuffixMethodInterceptor( String suffix )
- {
- this.suffix = suffix;
- }
-
- public Object invoke( MethodInvocation methodInvocation ) throws Throwable
- {
- return methodInvocation.proceed() + suffix;
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/TestSerializingInterceptor.java b/src/test/java/org/apache/commons/proxy/interceptor/TestSerializingInterceptor.java
deleted file mode 100644
index cb29b37..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/TestSerializingInterceptor.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.proxy.interceptor;
-
-import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.util.AbstractTestCase;
-
-import java.io.ByteArrayOutputStream;
-
-public class TestSerializingInterceptor extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerialization()
- {
- assertSerializable(new SerializingInterceptor());
- }
-
- public void testWithInvalidParameterType()
- {
- try
- {
- final ObjectEchoImpl target = new ObjectEchoImpl();
- ObjectEcho echo =
- ( ObjectEcho ) new ProxyFactory().createInterceptorProxy(target,
- new SerializingInterceptor(),
- new Class[] {ObjectEcho.class});
- final Object originalParameter = new ByteArrayOutputStream();
- echo.echoBack(originalParameter);
- fail("Should not be able to call method with non-serializable parameter type.");
- }
- catch( RuntimeException e )
- {
- }
- }
-
- public void testWithSerializableParametersAndReturn()
- {
- final ObjectEchoImpl target = new ObjectEchoImpl();
- ObjectEcho echo =
- ( ObjectEcho ) new ProxyFactory().createInterceptorProxy(target,
- new SerializingInterceptor(),
- new Class[] {ObjectEcho.class});
- final Object originalParameter = "Hello, World!";
- final Object returnValue = echo.echoBack(originalParameter);
- assertNotSame(originalParameter, target.parameter);
- assertNotSame(originalParameter, returnValue);
- assertNotSame(returnValue, target.parameter);
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- public static interface ObjectEcho
- {
- public Object echoBack( Object object );
- }
-
- public static class ObjectEchoImpl implements ObjectEcho
- {
- private Object parameter;
-
- public Object echoBack( Object object )
- {
- this.parameter = object;
- return object;
- }
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/filter/TestPatternFilter.java b/src/test/java/org/apache/commons/proxy/interceptor/filter/TestPatternFilter.java
deleted file mode 100644
index 165abbe..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/filter/TestPatternFilter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.proxy.interceptor.filter;
-
-import junit.framework.TestCase;
-import org.apache.commons.proxy.interceptor.MethodFilter;
-
-import java.util.Date;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class TestPatternFilter extends TestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testAccepts() throws Exception
- {
- final MethodFilter filter = PatternFilter.getterSetterFilter();
- assertTrue(filter.accepts(Date.class.getMethod("getSeconds", new Class[] {})));
- assertTrue(filter.accepts(Date.class.getMethod("getMinutes", new Class[] {})));
- assertTrue(filter.accepts(Date.class.getMethod("setSeconds", new Class[] {Integer.TYPE})));
- assertTrue(filter.accepts(Date.class.getMethod("setMinutes", new Class[] {Integer.TYPE})));
- assertFalse(filter.accepts(Date.class.getMethod("toString", new Class[] {})));
- assertFalse(filter.accepts(Date.class.getMethod("hashCode", new Class[] {})));
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/filter/TestReturnTypeFilter.java b/src/test/java/org/apache/commons/proxy/interceptor/filter/TestReturnTypeFilter.java
deleted file mode 100644
index 6ab7862..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/filter/TestReturnTypeFilter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.proxy.interceptor.filter;
-
-import junit.framework.TestCase;
-
-public class TestReturnTypeFilter extends TestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testAcceptsMethod() throws Exception
- {
- final ReturnTypeFilter filter = new ReturnTypeFilter(new Class[] {String.class, Integer.TYPE});
- assertTrue(filter.accepts(Object.class.getMethod("toString", new Class[] {})));
- assertTrue(filter.accepts(Object.class.getMethod("hashCode", new Class[] {})));
- assertFalse(filter.accepts(Object.class.getMethod("equals", new Class[] {Object.class})));
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/interceptor/filter/TestSimpleFilter.java b/src/test/java/org/apache/commons/proxy/interceptor/filter/TestSimpleFilter.java
deleted file mode 100644
index 366393d..0000000
--- a/src/test/java/org/apache/commons/proxy/interceptor/filter/TestSimpleFilter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.proxy.interceptor.filter;
-
-import junit.framework.TestCase;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-
-/**
- * @author James Carman
- * @since 1.0
- */
-public class TestSimpleFilter extends TestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testAccepts() throws Exception
- {
- final SimpleFilter filter = new SimpleFilter(new String[] {"echoBack"});
- assertTrue(filter.accepts(Echo.class.getMethod("echoBack", new Class[] {String.class})));
- assertFalse(filter.accepts(EchoImpl.class.getMethod("hashCode", new Class[] {})));
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java b/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java
deleted file mode 100644
index 9daa136..0000000
--- a/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.ProxyFactory;
-
-/**
- * @since 1.1
- */
-public class TestChainInvoker extends AbstractTestCase
-{
- public void testSkipDefaultValues()
- {
- final ChainInvoker invoker = new ChainInvoker(new Object[]{new DefaultTester(), new NonDefaultTester()});
- Tester tester = (Tester)new ProxyFactory().createInvokerProxy(invoker, new Class[] { Tester.class });
- assertEquals(true,tester.booleanMethod());
- assertEquals(1, tester.byteMethod());
- assertEquals('1', tester.charMethod());
- assertEquals(1.0, tester.doubleMethod(), 0.0);
- assertEquals(1.0f, tester.floatMethod(), 0.0f);
- assertEquals(1, tester.intMethod());
- assertEquals(1, tester.longMethod());
- assertEquals(1, tester.shortMethod());
- assertEquals("One", tester.objectMethod());
- }
-
- public void testReturnDefaultValue()
- {
- final ChainInvoker invoker = new ChainInvoker(new Object[]{new DefaultTester(), new DefaultTester()});
- Tester tester = (Tester)new ProxyFactory().createInvokerProxy(invoker, new Class[] { Tester.class });
- assertEquals(false,tester.booleanMethod());
- assertEquals(0, tester.byteMethod());
- assertEquals(0, tester.charMethod());
- assertEquals(0.0, tester.doubleMethod(), 0.0);
- assertEquals(0.0f, tester.floatMethod(), 0.0f);
- assertEquals(0, tester.intMethod());
- assertEquals(0, tester.longMethod());
- assertEquals(0, tester.shortMethod());
- assertEquals(null, tester.objectMethod());
- }
-
- public static interface Tester
- {
- public int intMethod();
-
- public long longMethod();
-
- public short shortMethod();
-
- public byte byteMethod();
-
- public double doubleMethod();
-
- public float floatMethod();
-
- public boolean booleanMethod();
-
- public char charMethod();
-
- public Object objectMethod();
- }
-
- public class NonDefaultTester implements Tester
- {
- public boolean booleanMethod()
- {
- return true;
- }
-
- public byte byteMethod()
- {
- return 1;
- }
-
- public char charMethod()
- {
- return '1';
- }
-
- public double doubleMethod()
- {
- return 1.0;
- }
-
- public float floatMethod()
- {
- return 1.0f;
- }
-
- public int intMethod()
- {
- return 1;
- }
-
- public long longMethod()
- {
- return 1;
- }
-
- public Object objectMethod()
- {
- return "One";
- }
-
- public short shortMethod()
- {
- return 1;
- }
- }
-
- public class DefaultTester implements Tester
- {
- public boolean booleanMethod()
- {
- return false;
- }
-
- public byte byteMethod()
- {
- return 0;
- }
-
- public char charMethod()
- {
- return 0;
- }
-
- public double doubleMethod()
- {
- return 0;
- }
-
- public float floatMethod()
- {
- return 0;
- }
-
- public int intMethod()
- {
- return 0;
- }
-
- public long longMethod()
- {
- return 0;
- }
-
- public Object objectMethod()
- {
- return null;
- }
-
- public short shortMethod()
- {
- return 0;
- }
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java b/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java
deleted file mode 100644
index 353e62d..0000000
--- a/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.provider.ConstantProvider;
-import org.apache.commons.proxy.util.AbstractTestCase;
-
-import java.io.Serializable;
-
-/**
- *
- */
-public class TestDuckTypingInvoker extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testExactSignatureMatch()
- {
- final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
- final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- final Duck duck = ( Duck ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {Duck.class});
- assertEquals("Quack!", duck.sayQuack());
- }
-
- public void testMismatchingParameterType()
- {
- final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
- final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- final ParameterizedDuck parameterizedDuck = ( ParameterizedDuck ) new ProxyFactory()
- .createInvokerProxy(invoker, new Class[] {ParameterizedDuck.class});
- try
- {
- parameterizedDuck.sayQuack("Elmer");
- fail("No matching method should be found.");
- }
- catch( UnsupportedOperationException e )
- {
- // Do nothing, expected behavior!
- }
- }
-
- public void testMismatchingReturnType()
- {
- final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
- final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- final VoidReturnDuck voidDuck = ( VoidReturnDuck ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {
- VoidReturnDuck.class});
- try
- {
- voidDuck.sayQuack();
- fail("No matching method should be found.");
- }
- catch( UnsupportedOperationException e )
- {
- // Do nothing, expected behavior!
- }
- }
-
- public void testNoMatchingMethod()
- {
- final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
- final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- final Goose goose = ( Goose ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {Goose.class});
- try
- {
- goose.sayHonk();
- fail("No matching method should be found.");
- }
- catch( UnsupportedOperationException e )
- {
- // Do nothing, expected behavior!
- }
- }
-
- public void testSerialization()
- {
- final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
- final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- assertSerializable(invoker);
- }
-
- public void testTargetHasCompatibleReturnType()
- {
- final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
- final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
- final SerializableDuck duck = ( SerializableDuck ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {
- SerializableDuck.class});
- assertEquals("Quack!", duck.sayQuack());
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- public interface Duck
- {
- public String sayQuack();
- }
-
- public interface Goose
- {
- public void sayHonk();
- }
-
- public static class LegacyDuck implements Serializable
- {
- public String sayQuack()
- {
- return "Quack!";
- }
- }
-
- public interface ParameterizedDuck
- {
- public String sayQuack( String recipient );
- }
-
- public interface SerializableDuck
- {
- public Serializable sayQuack();
- }
-
- public interface VoidReturnDuck
- {
- public void sayQuack();
- }
-}
diff --git a/src/test/java/org/apache/commons/proxy/invoker/TestInvocationHandlerAdapter.java b/src/test/java/org/apache/commons/proxy/invoker/TestInvocationHandlerAdapter.java
deleted file mode 100644
index ebd337c..0000000
--- a/src/test/java/org/apache/commons/proxy/invoker/TestInvocationHandlerAdapter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.factory.javassist.JavassistProxyFactory;
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.util.Echo;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
-public class TestInvocationHandlerAdapter extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerialization()
- {
- assertSerializable( new InvocationHandlerAdapter( new InvocationHandlerTester() ) );
- }
-
- public void testMethodInvocation() throws Exception
- {
- InvocationHandlerTester tester = new InvocationHandlerTester();
- final Echo echo = ( Echo ) new JavassistProxyFactory().createInvokerProxy(new InvocationHandlerAdapter(tester), new Class[] {Echo.class});
- echo.echoBack("hello");
- assertEquals(Echo.class.getMethod("echoBack", new Class[] {String.class}), tester.method);
- assertSame(echo, tester.proxy);
- assertNotNull(tester.arguments);
- assertEquals(1, tester.arguments.length);
- assertEquals("hello", tester.arguments[0]);
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- private static class InvocationHandlerTester implements InvocationHandler, Serializable
- {
- private Object proxy;
- private Method method;
- private Object[] arguments;
-
- public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
- {
- this.proxy = proxy;
- this.method = method;
- this.arguments = args;
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/invoker/TestNullInvoker.java b/src/test/java/org/apache/commons/proxy/invoker/TestNullInvoker.java
deleted file mode 100644
index 0b9c6f9..0000000
--- a/src/test/java/org/apache/commons/proxy/invoker/TestNullInvoker.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import org.apache.commons.proxy.ProxyUtils;
-import org.apache.commons.proxy.factory.cglib.CglibProxyFactory;
-import org.apache.commons.proxy.util.AbstractTestCase;
-
-public class TestNullInvoker extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testReturnValues()
- {
- final Tester tester = ( Tester ) ProxyUtils.createNullObject(new CglibProxyFactory(), new Class[] {Tester.class});
- assertEquals(0, tester.intMethod());
- assertEquals(0L, tester.longMethod());
- assertEquals(( short ) 0, tester.shortMethod());
- assertEquals(( byte ) 0, tester.byteMethod());
- assertEquals(( char ) 0, tester.charMethod());
- assertEquals(0.0f, tester.floatMethod(), 0.0f);
- assertEquals(0.0, tester.doubleMethod(), 0.0f);
- assertFalse(tester.booleanMethod());
- assertNull(tester.stringMethod());
- }
-
- public void testSerialization()
- {
- assertSerializable(new NullInvoker());
- }
-
-//**********************************************************************************************************************
-// Inner Classes
-//**********************************************************************************************************************
-
- public static interface Tester
- {
- public int intMethod();
-
- public long longMethod();
-
- public short shortMethod();
-
- public byte byteMethod();
-
- public char charMethod();
-
- public double doubleMethod();
-
- public float floatMethod();
-
- public String stringMethod();
-
- public boolean booleanMethod();
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/invoker/TestXmlRpcInvoker.java b/src/test/java/org/apache/commons/proxy/invoker/TestXmlRpcInvoker.java
deleted file mode 100644
index 5a2cc56..0000000
--- a/src/test/java/org/apache/commons/proxy/invoker/TestXmlRpcInvoker.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.proxy.invoker;
-
-import junit.extensions.TestSetup;
-import junit.framework.Protectable;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.framework.TestSuite;
-import org.apache.commons.proxy.exception.InvokerException;
-import org.apache.commons.proxy.factory.cglib.CglibProxyFactory;
-import org.apache.commons.proxy.util.Echo;
-import org.apache.commons.proxy.util.EchoImpl;
-import org.apache.xmlrpc.WebServer;
-import org.apache.xmlrpc.XmlRpcClient;
-import org.apache.xmlrpc.XmlRpcClientLite;
-
-/**
- * @author James Carman
- */
-public class TestXmlRpcInvoker extends TestCase
-{
-//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
- private static WebServer server;
- private static XmlRpcClient client;
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
- public static Test suite()
- {
- return new TestSetup(new TestSuite(TestXmlRpcInvoker.class))
- {
- public void run( final TestResult testResult )
- {
- Protectable p = new Protectable()
- {
- public void protect() throws Throwable
- {
- try
- {
- setUp();
- basicRun(testResult);
- }
- finally
- {
- tearDown();
- }
- }
- };
- testResult.runProtected(this, p);
- }
-
- protected void setUp() throws Exception
- {
- server = new WebServer(9999);
- server.addHandler("echo", new EchoImpl());
- server.start();
- client = new XmlRpcClientLite("http://localhost:9999/RPC2");
- }
-
- protected void tearDown() throws Exception
- {
- server.shutdown();
- }
- };
- }
-
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testInvalidHandlerName()
- {
- final XmlRpcInvoker handler = new XmlRpcInvoker(client, "invalid");
- final Echo echo = ( Echo ) new CglibProxyFactory()
- .createInvokerProxy(handler, new Class[] {Echo.class});
- try
- {
- echo.echoBack("Hello");
- fail();
- }
- catch( InvokerException e )
- {
- }
- }
-
- public void testValidInvocation() throws Exception
- {
- final XmlRpcInvoker handler = new XmlRpcInvoker(client, "echo");
- final Echo echo = ( Echo ) new CglibProxyFactory()
- .createInvokerProxy(handler, new Class[] {Echo.class});
- assertEquals("Hello", echo.echoBack("Hello"));
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/provider/remoting/TestBurlapProvider.java b/src/test/java/org/apache/commons/proxy/provider/remoting/TestBurlapProvider.java
deleted file mode 100644
index f3dcc3a..0000000
--- a/src/test/java/org/apache/commons/proxy/provider/remoting/TestBurlapProvider.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import org.apache.commons.proxy.exception.ObjectProviderException;
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.util.Echo;
-
-public class TestBurlapProvider extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerialization()
- {
- final BurlapProvider p = new BurlapProvider();
- p.setServiceInterface(Echo.class);
- p.setUrl("a malformed URL");
- assertSerializable(p);
- }
-
- public void testWithMalformedUrl()
- {
- try
- {
- final BurlapProvider p = new BurlapProvider(Echo.class, "a malformed URL");
- p.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
- }
-
- public void testWithMalformedUrlBean()
- {
- try
- {
- final BurlapProvider p = new BurlapProvider();
- p.setServiceInterface(Echo.class);
- p.setUrl("a malformed URL");
- p.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/provider/remoting/TestHessianProvider.java b/src/test/java/org/apache/commons/proxy/provider/remoting/TestHessianProvider.java
deleted file mode 100644
index e002b90..0000000
--- a/src/test/java/org/apache/commons/proxy/provider/remoting/TestHessianProvider.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.proxy.provider.remoting;
-
-import org.apache.commons.proxy.exception.ObjectProviderException;
-import org.apache.commons.proxy.util.AbstractTestCase;
-import org.apache.commons.proxy.util.Echo;
-
-public class TestHessianProvider extends AbstractTestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- public void testSerialization()
- {
- final HessianProvider p = new HessianProvider();
- p.setServiceInterface(Echo.class);
- p.setUrl("a malformed URL");
- assertSerializable(p);
- }
-
- public void testWithMalformedUrl()
- {
- try
- {
- final HessianProvider p = new HessianProvider(Echo.class, "a malformed URL");
- p.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
- }
-
- public void testWithMalformedUrlBean()
- {
- try
- {
- final HessianProvider p = new HessianProvider();
- p.setServiceInterface(Echo.class);
- p.setUrl("a malformed URL");
- p.getObject();
- fail();
- }
- catch( ObjectProviderException e )
- {
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/commons/proxy/util/AbstractTestCase.java b/src/test/java/org/apache/commons/proxy/util/AbstractTestCase.java
deleted file mode 100644
index 430c4fd..0000000
--- a/src/test/java/org/apache/commons/proxy/util/AbstractTestCase.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.apache.commons.proxy.util;
-
-import junit.framework.TestCase;
-import org.apache.commons.lang.SerializationUtils;
-
-import java.io.Serializable;
-
-/**
- * @author James Carman
- * @since 1.1
- */
-public abstract class AbstractTestCase extends TestCase
-{
-//**********************************************************************************************************************
-// Other Methods
-//**********************************************************************************************************************
-
- protected void assertSerializable( Object o )
- {
- assertTrue(o instanceof Serializable);
- SerializationUtils.clone(( Serializable ) o);
- }
-}
diff --git a/test/pom.xml b/test/pom.xml
new file mode 100644
index 0000000..7f42ec8
--- /dev/null
+++ b/test/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>commons-proxy2-parent</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>commons-proxy2-test</artifactId>
+ <name>Commons Proxy Test</name>
+ <description>Tests things that depend on multiple modules</description>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2-jdk</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2-cglib</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib-nodep</artifactId>
+ <version>2.1_3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy2-javassist</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/test/src/main/resources/dummy b/test/src/main/resources/dummy
new file mode 100644
index 0000000..421376d
--- /dev/null
+++ b/test/src/main/resources/dummy
@@ -0,0 +1 @@
+dummy
diff --git a/test/src/test/java/org/apache/commons/proxy2/DefaultProxyFactoryTest.java b/test/src/test/java/org/apache/commons/proxy2/DefaultProxyFactoryTest.java
new file mode 100644
index 0000000..a5657e0
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/DefaultProxyFactoryTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Proxy;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test the default ProxyFactory provided by {@link ProxyUtils}.
+ */
+public class DefaultProxyFactoryTest {
+ private ProxyFactory proxyFactory;
+
+ @Before
+ public void setUp() {
+ proxyFactory = ProxyUtils.proxyFactory();
+ }
+
+ @Test
+ public void testBasic() {
+ Foo foo = proxyFactory.createInvokerProxy(NullInvoker.INSTANCE,
+ Foo.class);
+ assertNotNull(foo);
+ assertTrue(foo instanceof Proxy);
+ }
+
+ @Test
+ public void testSubclassing() {
+ Bar bar = proxyFactory.createInvokerProxy(NullInvoker.INSTANCE,
+ Bar.class);
+ assertNotNull(bar);
+ }
+
+ @Test
+ public void testCombined() {
+ Bar bar = proxyFactory.createInvokerProxy(NullInvoker.INSTANCE,
+ Bar.class, Foo.class);
+ assertNotNull(bar);
+ assertTrue(bar instanceof Foo);
+ }
+
+ public interface Foo {
+ }
+
+ public static class Bar {
+ }
+}
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/AbstractStubTestCase.java b/test/src/test/java/org/apache/commons/proxy2/stub/AbstractStubTestCase.java
new file mode 100644
index 0000000..534a26d
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/AbstractStubTestCase.java
@@ -0,0 +1,441 @@
+package org.apache.commons.proxy2.stub;
+
+import org.apache.commons.proxy2.ProxyFactory;
+import org.apache.commons.proxy2.cglib.CglibProxyFactory;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.apache.commons.proxy2.provider.ObjectProviderUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public abstract class AbstractStubTestCase
+{
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Fields
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ protected ProxyFactory proxyFactory;
+ protected StubInterface target;
+
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Abstract Methods
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ protected abstract StubInterface createProxy(Trainer<StubInterface> trainer);
+
+ // ----------------------------------------------------------------------------------------------------------------------
+ // Other Methods
+ // ----------------------------------------------------------------------------------------------------------------------
+
+ @Before
+ public final void setUpProxyFactory()
+ {
+ this.proxyFactory = new CglibProxyFactory();
+ this.target = proxyFactory.createInvokerProxy(NullInvoker.INSTANCE, StubInterface.class);
+ }
+
+ @Test
+ public void testAnyMatcher()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one(any(String.class))).thenReturn("World");
+ }
+ });
+ assertEquals("World", proxy.one("Hello"));
+ assertEquals("World", proxy.one(null));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testMixingArgumentMatchingStrategies()
+ {
+ createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.three(isInstance(String.class), "World"))
+ .thenAnswer(ObjectProviderUtils.constant("World"));
+ }
+ });
+ }
+
+ @Test
+ public void testStubReturn()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.stub()).thenStub(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Hello")).thenReturn("World");
+ }
+ });
+ }
+ });
+ assertNotNull(proxy.stub());
+ assertEquals("World", proxy.stub().one("Hello"));
+ }
+
+ @Test
+ public void testStubArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.stubs()).thenBuildArray().addElement(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Whatever")).thenReturn("Zero");
+ }
+ }).addElement(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Whatever")).thenReturn("One");
+ }
+ })
+ .build();
+ }
+ });
+
+ assertEquals("Zero", proxy.stubs()[0].one("Whatever"));
+ assertEquals("One", proxy.stubs()[1].one("Whatever"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testThenBeforeWhen()
+ {
+ createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ thenThrow(new RuntimeException("Oops!"));
+ }
+ });
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testThrowExceptionWithException()
+ {
+ StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ trainee.voidMethod("Hello");
+ thenThrow(new IllegalArgumentException("Nope!"));
+ }
+ });
+ proxy.voidMethod("Hello");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testThrowExceptionWithProvidedException()
+ {
+ StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ trainee.voidMethod("Hello");
+ thenThrow(ObjectProviderUtils.constant(new IllegalArgumentException("Nope!")));
+ }
+ });
+ proxy.voidMethod("Hello");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testThrowingExceptionObject()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Hello")).thenThrow(new RuntimeException("No way, Jose!"));
+ }
+ });
+ proxy.one("Hello");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testThrowingProvidedException()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Hello")).thenThrow(
+ ObjectProviderUtils.constant(new RuntimeException("No way, Jose!")));
+ }
+ });
+ proxy.one("Hello");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testUsingWrongStub()
+ {
+ createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(final StubInterface parent)
+ {
+ when(parent.stub()).thenStub(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(final StubInterface child)
+ {
+ when(parent.one("Hello")).thenReturn("World");
+ }
+ });
+ }
+ });
+ }
+
+ @Test
+ public void testWithArgumentMatchers()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one(isInstance(String.class))).thenAnswer(ObjectProviderUtils.constant("World"));
+ }
+ });
+ assertEquals("World", proxy.one("Hello"));
+ assertEquals("World", proxy.one("Whatever"));
+ }
+
+ @Test
+ public void testWithArrayParameter()
+ {
+ StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.arrayParameter("One", "Two", "Three")).thenReturn("Four");
+ }
+ });
+
+ assertEquals("Four", proxy.arrayParameter("One", "Two", "Three"));
+ }
+
+ @Test
+ public void testWithBooleanArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.booleanArray()).thenReturn(false, true, false);
+ }
+ });
+ assertTrue(Arrays.equals(new boolean[] { false, true, false }, proxy.booleanArray()));
+ }
+
+ @Test
+ public void testWithByteArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.byteArray()).thenReturn((byte) 1, (byte) 2);
+ }
+ });
+ assertArrayEquals(new byte[] { 1, 2 }, proxy.byteArray());
+ }
+
+ @Test
+ public void testWithCharArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.charArray()).thenReturn('a', 'b', 'c');
+ }
+ });
+ assertArrayEquals(new char[] { 'a', 'b', 'c' }, proxy.charArray());
+ }
+
+ @Test
+ public void testWithDoubleArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.doubleArray()).thenReturn(1.0, 2.0);
+ }
+ });
+ assertArrayEquals(new double[] { 1.0, 2.0 }, proxy.doubleArray(), 0.0);
+ }
+
+ @Test
+ public void testWithFloatArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.floatArray()).thenReturn(1f, 2f);
+ }
+ });
+ assertArrayEquals(new float[] { 1f, 2f }, proxy.floatArray(), 0.0f);
+ }
+
+ @Test
+ public void testWithIntArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.intArray()).thenReturn(1, 2);
+ }
+ });
+ assertArrayEquals(new int[] { 1, 2 }, proxy.intArray());
+ }
+
+ @Test
+ public void testWithLongArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.longArray()).thenReturn(1, 2);
+ }
+ });
+ assertArrayEquals(new long[] { 1, 2 }, proxy.longArray());
+ }
+
+ @Test
+ public void testWithMismatchedArgument()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one(eq("Hello"))).thenReturn("World");
+ }
+ });
+ assertEquals("World", proxy.one("Hello"));
+ assertEquals(null, proxy.one("Whatever"));
+ }
+
+ @Test
+ public void testWithMultipleMethodsTrained()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Hello")).thenReturn("World");
+ when(trainee.two("Foo")).thenReturn("Bar");
+ }
+ });
+ assertEquals("World", proxy.one("Hello"));
+ assertEquals("Bar", proxy.two("Foo"));
+ }
+
+ @Test
+ public void testWithShortArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.shortArray()).thenReturn((short) 1, (short) 2);
+ }
+ });
+ assertArrayEquals(new short[] { 1, 2 }, proxy.shortArray());
+ }
+
+ @Test
+ public void testWithSingleMethodTrained()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Hello")).thenReturn("World");
+ }
+ });
+ assertEquals("World", proxy.one("Hello"));
+ assertEquals(null, proxy.two("Whatever"));
+ assertEquals(null, proxy.one("Mismatch!"));
+ }
+
+ @Test
+ public void testWithStringArray()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.stringArray()).thenReturn("One", "Two");
+ }
+ });
+ assertArrayEquals(new String[] { "One", "Two" }, proxy.stringArray());
+ }
+
+ /*
+ * This test replicates #thenStub() functionality in a more "ignorant" (ergo versatile) manner.
+ */
+ @Test
+ public void testInterruptResume()
+ {
+ final StubInterface proxy = createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.stub()).thenReturn(createProxy(new Trainer<StubInterface>()
+ {
+ @Override
+ protected void train(StubInterface trainee)
+ {
+ when(trainee.one("Hello")).thenReturn("World");
+ }
+ }));
+ }
+ });
+ assertNotNull(proxy.stub());
+ assertEquals("World", proxy.stub().one("Hello"));
+ }
+}
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java b/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java
new file mode 100644
index 0000000..d6f2bf0
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/AnnotationBuilderTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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 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;
+
+/**
+ * Test {@link AnnotationFactory}.
+ */
+public class AnnotationBuilderTest
+{
+ @Test
+ public void testDefaultAnnotation()
+ {
+ final CustomAnnotation customAnnotation = AnnotationBuilder.buildDefault(CustomAnnotation.class);
+ assertEquals(CustomAnnotation.class, customAnnotation.annotationType());
+ assertEquals("", customAnnotation.annString());
+ assertEquals(0, customAnnotation.finiteValues().length);
+ assertNull(customAnnotation.someType());
+ }
+
+ @Test
+ public void testStubbedAnnotation()
+ {
+ final CustomAnnotation customAnnotation = AnnotationBuilder.of(CustomAnnotation.class)
+ .train(new AnnotationTrainer<CustomAnnotation>()
+ {
+ @Override
+ protected void train(CustomAnnotation trainee)
+ {
+ when(trainee.someType()).thenReturn(Object.class).when(trainee.finiteValues())
+ .thenReturn(FiniteValues.ONE, FiniteValues.THREE).when(trainee.annString())
+ .thenReturn("hey");
+ }
+ }).build();
+
+ assertEquals(CustomAnnotation.class, customAnnotation.annotationType());
+ assertEquals("hey", customAnnotation.annString());
+ assertArrayEquals(new FiniteValues[] { FiniteValues.ONE, FiniteValues.THREE }, customAnnotation.finiteValues());
+ assertEquals(Object.class, customAnnotation.someType());
+ }
+
+ @Test
+ public void testNestedStubbedAnnotation()
+ {
+ final NestingAnnotation nestingAnnotation = AnnotationBuilder.of(NestingAnnotation.class)
+ .train(new AnnotationTrainer<NestingAnnotation>()
+ {
+ @Override
+ protected void train(NestingAnnotation trainee)
+ {
+ when(trainee.child()).thenStub(CustomAnnotation.class).when(trainee.somethingElse())
+ .thenReturn("somethingElse");
+ }
+ }).build();
+
+ assertEquals("", nestingAnnotation.child().annString());
+ assertEquals(0, nestingAnnotation.child().finiteValues().length);
+ assertEquals(null, nestingAnnotation.child().someType());
+ 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
+ public void testNestedStubbedAnnotationArray()
+ {
+ final NestingAnnotation nestingAnnotation = AnnotationBuilder.of(NestingAnnotation.class)
+ .train(new AnnotationTrainer<NestingAnnotation>()
+ {
+
+ @Override
+ protected void train(NestingAnnotation trainee)
+ {
+ when(trainee.children()).thenBuildArray().addElement(new AnnotationTrainer<CustomAnnotation>()
+ {
+ @Override
+ protected void train(CustomAnnotation trainee)
+ {
+ when(trainee.finiteValues()).thenReturn(FiniteValues.ONE, FiniteValues.THREE);
+ }
+ }).addElement(new AnnotationTrainer<CustomAnnotation>()
+ {
+ @Override
+ protected void train(CustomAnnotation trainee)
+ {
+ when(trainee.finiteValues()).thenReturn(FiniteValues.TWO);
+ }
+ }).build();
+ }
+ }).build();
+
+ assertNull(nestingAnnotation.child());
+ assertEquals(2, nestingAnnotation.children().length);
+ assertArrayEquals(new FiniteValues[] { FiniteValues.ONE, FiniteValues.THREE },
+ nestingAnnotation.children()[0].finiteValues());
+ assertArrayEquals(new FiniteValues[] { FiniteValues.TWO }, nestingAnnotation.children()[1].finiteValues());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadMemberMap()
+ {
+ AnnotationBuilder.of(CustomAnnotation.class).withMembers(
+ Collections.singletonMap("annString", Integer.valueOf(100)));
+ }
+
+ public @interface NestingAnnotation
+ {
+ CustomAnnotation child();
+
+ String somethingElse();
+
+ CustomAnnotation[] children() default {};
+ }
+
+ public @interface CustomAnnotation
+ {
+ String annString() default "";
+
+ FiniteValues[] finiteValues() default {};
+
+ Class<?> someType();
+ }
+
+ public enum FiniteValues
+ {
+ ONE, TWO, THREE;
+ }
+
+}
\ No newline at end of file
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/RetentionWrapper.java b/test/src/test/java/org/apache/commons/proxy2/stub/RetentionWrapper.java
new file mode 100644
index 0000000..2976eba
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/RetentionWrapper.java
@@ -0,0 +1,34 @@
+/*
+ * 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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RetentionWrapper
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ Retention value();
+}
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/StubBuilderTest.java b/test/src/test/java/org/apache/commons/proxy2/stub/StubBuilderTest.java
new file mode 100644
index 0000000..d81ec2d
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/StubBuilderTest.java
@@ -0,0 +1,236 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.proxy2.ObjectProvider;
+import org.apache.commons.proxy2.provider.BeanProvider;
+import org.apache.commons.proxy2.provider.ObjectProviderUtils;
+import org.junit.Test;
+
+public class StubBuilderTest extends AbstractStubTestCase
+{
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+
+ @Override
+ protected StubInterface createProxy(Trainer<StubInterface> trainer)
+ {
+ return new StubBuilder<StubInterface>(proxyFactory, StubInterface.class).train(trainer).build();
+ }
+
+ @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 trainee)
+ {
+ when(trainee.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 trainee)
+ {
+ when(trainee.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 trainee)
+ {
+ when(trainee.one("Foo")).thenReturn("Bar");
+ }
+ });
+ StubInterface stub = builder.build();
+ assertEquals("Bar", stub.one("Foo"));
+ }
+
+ @Test
+ public void testAdditionalInterfaces() {
+ StubBuilder<StubInterface> builder = new StubBuilder<StubInterface>(proxyFactory, StubInterface.class,
+ ObjectProviderUtils.constant(new SimpleStub()));
+ builder.train(new Trainer<Iterable<String>>()
+ {
+
+ @Override
+ protected void train(Iterable<String> trainee)
+ {
+ when(trainee.iterator()).thenAnswer(new ObjectProvider<Iterator<String>>()
+ {
+ @Override
+ public Iterator<String> getObject()
+ {
+ return Arrays.asList("foo", "bar", "baz").iterator();
+ }
+ });
+ }
+ });
+ builder.addProxyTypes(Cloneable.class, Marker.class);
+ StubInterface stub = builder.build();
+ assertTrue(stub instanceof Iterable<?>);
+ assertTrue(stub instanceof Cloneable);
+ assertTrue(stub instanceof Marker);
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// 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)
+ {
+
+ }
+
+ @Override
+ public StubInterface stub()
+ {
+ return null;
+ }
+
+ @Override
+ public StubInterface[] stubs()
+ {
+ return new StubInterface[0];
+ }
+ }
+
+ public interface Marker
+ {
+ }
+}
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/StubInterceptorBuilderTest.java b/test/src/test/java/org/apache/commons/proxy2/stub/StubInterceptorBuilderTest.java
new file mode 100644
index 0000000..618038b
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/StubInterceptorBuilderTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.Interceptor;
+import org.apache.commons.proxy2.invoker.NullInvoker;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import static org.junit.Assert.*;
+
+public class StubInterceptorBuilderTest extends AbstractStubTestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private StubInterceptorBuilder builder;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ @Before
+ public void initialize()
+ {
+ builder = new StubInterceptorBuilder(proxyFactory);
+ }
+
+ @Override
+ protected StubInterface createProxy(Trainer<StubInterface> trainer)
+ {
+ Interceptor interceptor = builder.train(trainer).build();
+ return proxyFactory.createInterceptorProxy(
+ proxyFactory.createInvokerProxy(NullInvoker.INSTANCE, StubInterface.class),
+ interceptor,
+ StubInterface.class);
+ }
+
+ @Test
+ public void testWithNestedAnnotations()
+ {
+ Interceptor interceptor = builder.train(new Trainer<RetentionWrapper>()
+ {
+ @Override
+ protected void train(RetentionWrapper trainee)
+ {
+
+ when(trainee.value()).thenStub(new Trainer<Retention>()
+ {
+ @Override
+ protected void train(Retention trainee)
+ {
+ when(trainee.value()).thenReturn(RetentionPolicy.RUNTIME);
+ }
+ });
+ }
+ }).build();
+ RetentionWrapper wrapper = proxyFactory.createInterceptorProxy(proxyFactory.createInvokerProxy(NullInvoker.INSTANCE), interceptor, RetentionWrapper.class);
+ assertNotNull(wrapper.value());
+ assertEquals(RetentionPolicy.RUNTIME, wrapper.value().value());
+ }
+
+ @Test
+ public void testWithSimpleAnnotations()
+ {
+ Interceptor interceptor = builder.train(new Trainer<Retention>()
+ {
+ @Override
+ protected void train(Retention trainee)
+ {
+ when(trainee.value()).thenReturn(RetentionPolicy.RUNTIME);
+ }
+ }).build();
+ Retention wrapper = proxyFactory.createInterceptorProxy(proxyFactory.createInvokerProxy(NullInvoker.INSTANCE), interceptor, Retention.class);
+ assertEquals(RetentionPolicy.RUNTIME, wrapper.value());
+ }
+
+}
diff --git a/test/src/test/java/org/apache/commons/proxy2/stub/StubInterface.java b/test/src/test/java/org/apache/commons/proxy2/stub/StubInterface.java
new file mode 100644
index 0000000..1812f6b
--- /dev/null
+++ b/test/src/test/java/org/apache/commons/proxy2/stub/StubInterface.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+public interface StubInterface
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ String one(String value);
+ String three(String arg1, String arg2);
+ String two(String value);
+
+ byte[] byteArray();
+ char[] charArray();
+ short[] shortArray();
+ int[] intArray();
+ long[] longArray();
+ float[] floatArray();
+ double[] doubleArray();
+ boolean[] booleanArray();
+ String[] stringArray();
+
+ String arrayParameter(String... strings);
+
+ void voidMethod(String arg);
+
+ StubInterface stub();
+ StubInterface[] stubs();
+}