You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by jc...@apache.org on 2005/09/05 18:00:13 UTC
svn commit: r278784 - in /jakarta/commons/sandbox/proxy/trunk/src:
java/org/apache/commons/proxy/factory/javassist/
java/org/apache/commons/proxy/factory/util/
test/org/apache/commons/proxy/factory/
Author: jcarman
Date: Mon Sep 5 09:00:08 2005
New Revision: 278784
URL: http://svn.apache.org/viewcvs?rev=278784&view=rev
Log:
Implementing subclass proxy support.
Modified:
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractSubclassingProxyFactory.java
jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java
Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java?rev=278784&r1=278783&r2=278784&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistProxyFactory.java Mon Sep 5 09:00:08 2005
@@ -21,12 +21,11 @@
import javassist.CtConstructor;
import javassist.CtMethod;
import org.aopalliance.intercept.MethodInterceptor;
-import org.apache.commons.logging.LogFactory;
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.ProxyClassCache;
import org.apache.commons.proxy.factory.util.AbstractSubclassingProxyFactory;
+import org.apache.commons.proxy.factory.util.ProxyClassCache;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -124,8 +123,6 @@
proxyClass.addConstructor( proxyConstructor );
for( int i = 0; i < methods.length; ++i )
{
- LogFactory.getLog( getClass() )
- .debug( "Adding method " + methods[i] + " to delegating proxy class..." );
final CtMethod method = new CtMethod( JavassistUtils.resolve( methods[i].getReturnType() ),
methods[i].getName(),
JavassistUtils.resolve( methods[i].getParameterTypes() ),
Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java?rev=278784&r1=278783&r2=278784&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java Mon Sep 5 09:00:08 2005
@@ -21,12 +21,8 @@
import org.apache.commons.logging.LogFactory;
import org.apache.commons.proxy.ObjectProvider;
import org.apache.commons.proxy.ProxyFactory;
-import org.apache.commons.proxy.exception.ProxyFactoryException;
import java.lang.reflect.InvocationHandler;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Collection;
/**
* A helpful superclass for {@link org.apache.commons.proxy.ProxyFactory} implementations.
@@ -60,6 +56,24 @@
// ProxyFactory Implementation
//----------------------------------------------------------------------------------------------------------------------
+ /**
+ * 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;
+ }
+
public final Object createDelegatorProxy( ObjectProvider targetProvider, Class... proxyClasses )
{
return createDelegatorProxy( Thread.currentThread().getContextClassLoader(), targetProvider, proxyClasses );
@@ -76,18 +90,5 @@
{
return createInvocationHandlerProxy( Thread.currentThread().getContextClassLoader(), invocationHandler,
proxyClasses );
- }
-
- public boolean canProxy( Class... proxyClasses )
- {
- for( int i = 0; i < proxyClasses.length; i++ )
- {
- Class proxyClass = proxyClasses[i];
- if( !proxyClass.isInterface() )
- {
- return false;
- }
- }
- return true;
}
}
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=278784&r1=278783&r2=278784&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 Mon Sep 5 09:00:08 2005
@@ -18,6 +18,7 @@
import org.apache.commons.proxy.exception.ProxyFactoryException;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.LinkedList;
@@ -29,53 +30,21 @@
*/
public abstract class AbstractSubclassingProxyFactory extends AbstractProxyFactory
{
- /**
- * 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
- */
- protected static Class getSuperclass( Class... proxyClasses )
+//----------------------------------------------------------------------------------------------------------------------
+// Static Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ private static boolean hasSuitableDefaultConstructor( Class superclass )
{
- final Class[] superclasses = toNonInterfaces( proxyClasses );
- switch( superclasses.length )
+ for( Constructor constructor : superclass.getDeclaredConstructors() )
{
- 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." );
- }
- try
- {
- superclass.getConstructor();
- }
- catch( NoSuchMethodException e )
- {
- throw new ProxyFactoryException( "Proxy class cannot extend " + superclass.getName() + ", because it has no \"default\" constructor.", e );
- }
- 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() );
+ if( constructor.getParameterTypes().length == 0 && ( Modifier.isPublic( constructor.getModifiers() ) ||
+ Modifier.isProtected( constructor.getModifiers() ) ) )
+ {
+ return true;
+ }
}
+ return false;
}
/**
@@ -98,6 +67,29 @@
return ( Class[] ) interfaces.toArray( new Class[interfaces.size()] );
}
+ private static Class[] toNonInterfaces( Class... proxyClasses )
+ {
+ final List<Class> superclasses = new LinkedList<Class>();
+ 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
@@ -111,18 +103,50 @@
}
}
- private static Class[] toNonInterfaces( Class... proxyClasses )
+ /**
+ * 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 List<Class> superclasses = new LinkedList<Class>();
- for( int i = 0; i < proxyClasses.length; i++ )
+ final Class[] superclasses = toNonInterfaces( proxyClasses );
+ switch( superclasses.length )
{
- Class proxyClass = proxyClasses[i];
- if( !proxyClass.isInterface() )
- {
- superclasses.add( proxyClass );
- }
+ 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() );
}
- return ( Class[] ) superclasses.toArray( new Class[superclasses.size()] );
-
}
}
+
Modified: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java?rev=278784&r1=278783&r2=278784&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/AbstractSubclassingProxyFactoryTestCase.java Mon Sep 5 09:00:08 2005
@@ -37,6 +37,10 @@
{
assertTrue( factory.canProxy( Echo.class ) );
assertTrue( factory.canProxy( EchoImpl.class ) );
+ assertFalse( factory.canProxy( FinalEcho.class ) );
+ assertFalse( factory.canProxy( NoDefaultConstructorEcho.class ) );
+ assertTrue( factory.canProxy( ProtectedConstructorEcho.class ) );
+ assertFalse( factory.canProxy( InvisibleEcho.class ) );
}
public void testDelegatorWithSuperclass()
@@ -55,5 +59,30 @@
{
final Echo echo = ( Echo )factory.createInvocationHandlerProxy( new NullInvocationHandler(), Echo.class, EchoImpl.class );
assertTrue( echo instanceof EchoImpl );
+ }
+
+ public static final class FinalEcho extends EchoImpl
+ {
+
+ }
+
+ public static class NoDefaultConstructorEcho extends EchoImpl
+ {
+ public NoDefaultConstructorEcho( String param )
+ {
+ }
+ }
+
+ public static class ProtectedConstructorEcho extends EchoImpl
+ {
+ protected ProtectedConstructorEcho()
+ {
+
+ }
+ }
+
+ private static class InvisibleEcho extends EchoImpl
+ {
+
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org