Author: jcarman Date: Sat Nov 19 11:39:44 2005 New Revision: 345675 URL: http://svn.apache.org/viewcvs?rev=345675&view=rev Log: Made ProxyFactory a class and not an interface.
Added: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java (with props) Removed: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/reflect/ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/reflect/ Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/ProxyFactory.java jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/ProxyFactory.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/ProxyFactory.java?rev=345675&r1=345674&r2=345675&view=diff ============================================================================== --- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/ProxyFactory.java (original) +++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/ProxyFactory.java Sat Nov 19 11:39:44 2005 @@ -16,21 +16,50 @@ */ package org.apache.commons.proxy; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + /** - * A <code>ProxyFactory</code> essentially encapsulates a "proxying strategy". All Commons Proxy proxies - * are created using a <code>ProxyFactory</code>. So, to change the proxying strategy, simply provide a different + * A <code>ProxyFactory</code> essentially encapsulates a "proxying strategy". All Commons Proxy proxies are created + * using a <code>ProxyFactory</code>. So, to change the proxying strategy, simply provide a different * <code>ProxyFactory</code> implementation. * + * <p> + * <b>Note</b>: This class uses Java reflection. For more efficient proxies, try using either + * [EMAIL PROTECTED] org.apache.commons.proxy.factory.cglib.CglibProxyFactory CglibProxyFactory} or + * [EMAIL PROTECTED] org.apache.commons.proxy.factory.javassist.JavassistProxyFactory JavassistProxyFactory}. + * * @author James Carman * @version 1.0 */ -public interface ProxyFactory +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." * @@ -38,7 +67,10 @@ * @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 ); + 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>. @@ -49,63 +81,169 @@ * @return a proxy which delegates to the object provided by the target <code>delegateProvider> */ public Object createDelegatorProxy( ClassLoader classLoader, ObjectProvider delegateProvider, - Class[] proxyClasses ); + Class[] proxyClasses ) + { + return Proxy.newProxyInstance( classLoader, proxyClasses, + new DelegatorInvocationHandler( delegateProvider ) ); + } /** - * Creates a proxy which passes through a [EMAIL PROTECTED] Interceptor interceptor} before eventually reaching - * the <code>target</code> object. The proxy will be generated using the current thread's "context class loader." + * Creates a proxy which passes through a [EMAIL PROTECTED] 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 [EMAIL PROTECTED] Interceptor interceptor} before eventually reaching - * the <code>target</code> object. + * @return a proxy which passes through a [EMAIL PROTECTED] Interceptor interceptor} before eventually reaching the + * <code>target</code> object. */ - public Object createInterceptorProxy( Object target, Interceptor interceptor, Class[] proxyClasses ); + public Object createInterceptorProxy( Object target, Interceptor interceptor, + Class[] proxyClasses ) + { + return createInterceptorProxy( Thread.currentThread().getContextClassLoader(), target, interceptor, + proxyClasses ); + } /** - * Creates a proxy which passes through a [EMAIL PROTECTED] Interceptor interceptor} - * before eventually reaching the <code>target</code> object. + * Creates a proxy which passes through a [EMAIL PROTECTED] 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 [EMAIL PROTECTED] Interceptor interceptor} - * before eventually reaching the <code>target</code> object. + * @return a proxy which passes through a [EMAIL PROTECTED] Interceptor interceptor} before eventually reaching the + * <code>target</code> object. */ public Object createInterceptorProxy( ClassLoader classLoader, Object target, Interceptor interceptor, - Class[] proxyClasses ); + Class[] proxyClasses ) + { + return Proxy + .newProxyInstance( classLoader, proxyClasses, new InterceptorInvocationHandler( target, interceptor ) ); + } /** - * Creates a proxy which uses the provided [EMAIL PROTECTED] Invoker} to handle all method invocations. The proxy - * will be generated using the current thread's "context class loader." + * Creates a proxy which uses the provided [EMAIL PROTECTED] 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 + * @param invoker the invoker + * @param proxyClasses the interfaces that the proxy should implement * @return a proxy which uses the provided [EMAIL PROTECTED] Invoker} to handle all method invocations */ - public Object createInvokerProxy( Invoker invoker, Class[] proxyClasses ); + public Object createInvokerProxy( Invoker invoker, Class[] proxyClasses ) + { + return createInvokerProxy( Thread.currentThread().getContextClassLoader(), invoker, + proxyClasses ); + } /** * Creates a proxy which uses the provided [EMAIL PROTECTED] 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 + * @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 [EMAIL PROTECTED] Invoker} to handle all method invocations */ public Object createInvokerProxy( ClassLoader classLoader, Invoker invoker, - Class[] proxyClasses ); + Class[] proxyClasses ) + { + return Proxy.newProxyInstance( classLoader, proxyClasses, new InvokerInvocationHandler( invoker ) ); + } - /** - * Returns true if this proxy factory can generate a proxy class which extends/implements - * the <code>proxyClasses</code>. - * - * @param proxyClasses the desired proxy classes - * @return true if this proxy factory can generate a proxy class which extends/implements - * the <code>proxyClasses</code>. - */ - public boolean canProxy( Class[] proxyClasses ); +//---------------------------------------------------------------------------------------------------------------------- +// Inner Classes +//---------------------------------------------------------------------------------------------------------------------- + + private static class DelegatorInvocationHandler implements InvocationHandler + { + private final ObjectProvider delegateProvider; + protected DelegatorInvocationHandler( ObjectProvider delegateProvider ) + { + this.delegateProvider = delegateProvider; + } + + public Object invoke( 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 implements InvocationHandler + { + private final Object target; + private final Interceptor methodInterceptor; + public InterceptorInvocationHandler( Object target, Interceptor methodInterceptor ) + { + this.target = target; + this.methodInterceptor = methodInterceptor; + } + + public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable + { + final ReflectionInvocation invocation = new ReflectionInvocation( target, method, args ); + return methodInterceptor.intercept( invocation ); + } + } + + private static class ReflectionInvocation implements Invocation + { + 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 class InvokerInvocationHandler implements InvocationHandler + { + private final Invoker invoker; + public InvokerInvocationHandler( Invoker invoker ) + { + this.invoker = invoker; + } + + public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable + { + return invoker.invoke( proxy, method, args ); + } + } } Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java?rev=345675&r1=345674&r2=345675&view=diff ============================================================================== --- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java (original) +++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java Sat Nov 19 11:39:44 2005 @@ -16,6 +16,7 @@ */ package org.apache.commons.proxy.factory.util; +import org.apache.commons.proxy.ProxyFactory; import org.apache.commons.proxy.exception.ProxyFactoryException; import java.lang.reflect.Constructor; @@ -28,7 +29,7 @@ * @author James Carman * @version 1.0 */ -public abstract class AbstractSubclassingProxyFactory extends AbstractProxyFactory +public abstract class AbstractSubclassingProxyFactory extends ProxyFactory { //---------------------------------------------------------------------------------------------------------------------- // Static Methods Added: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java?rev=345675&view=auto ============================================================================== --- jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java (added) +++ jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java Sat Nov 19 11:39:44 2005 @@ -0,0 +1,26 @@ +/* $Id$ + * + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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 +{ + public TestProxyFactory() + { + super( new ProxyFactory() ); + } +} \ No newline at end of file Propchange: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/TestProxyFactory.java ------------------------------------------------------------------------------ svn:keywords = Id --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]