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/01 06:19:12 UTC
svn commit: r265645 - in /jakarta/commons/sandbox/proxy/trunk/src:
java/org/apache/commons/proxy/factory/
java/org/apache/commons/proxy/factory/cglib/
java/org/apache/commons/proxy/factory/javassist/
java/org/apache/commons/proxy/factory/reflect/ java/...
Author: jcarman
Date: Wed Aug 31 21:19:02 2005
New Revision: 265645
URL: http://svn.apache.org/viewcvs?rev=265645&view=rev
Log:
Refactored ProxyFactory support classes and JavassistProxyFactory implementation.
Added:
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java (with props)
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java (contents, props changed)
- copied, changed from r265575, jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/AbstractProxyFactory.java
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java (contents, props changed)
- copied, changed from r265575, jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/MethodSignature.java
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java (with props)
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java (with props)
jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/
jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java (contents, props changed)
- copied, changed from r265575, jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/TestMethodSignature.java
Removed:
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/AbstractProxyFactory.java
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/MethodSignature.java
jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/TestMethodSignature.java
Modified:
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java
jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistMethodInvocation.java
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/reflect/ReflectionProxyFactory.java
Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java?rev=265645&r1=265644&r2=265645&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/cglib/CglibProxyFactory.java Wed Aug 31 21:19:02 2005
@@ -22,7 +22,7 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.factory.AbstractProxyFactory;
+import org.apache.commons.proxy.factory.util.AbstractProxyFactory;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistMethodInvocation.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistMethodInvocation.java?rev=265645&r1=265644&r2=265645&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistMethodInvocation.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/javassist/JavassistMethodInvocation.java Wed Aug 31 21:19:02 2005
@@ -21,12 +21,13 @@
import javassist.CtConstructor;
import javassist.CtMethod;
import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import java.lang.ref.WeakReference;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
/**
* @author James Carman
@@ -34,13 +35,12 @@
*/
public abstract class JavassistMethodInvocation implements MethodInvocation
{
- // TODO: Make sure this doesn't cause memory leaks in application servers!
- private static final HashMap<CacheKey,Class> invocationClassCache = new HashMap<CacheKey,Class>();
- private static final Log log = LogFactory.getLog( JavassistMethodInvocation.class );
+ private static WeakHashMap<ClassLoader, Map<String, WeakReference<Class>>> loaderToClassCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class>>>();
+
protected final Method method;
protected final Object target;
protected final Object[] arguments;
-
+
public JavassistMethodInvocation( Method method, Object target, Object[] arguments )
{
this.method = method;
@@ -68,106 +68,99 @@
return method;
}
+ 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;
+ }
+ private static String toClassCacheKey( Method method )
+ {
+ return String.valueOf( method );
+ }
public synchronized static Class getMethodInvocationClass( ClassLoader classLoader, Method interfaceMethod )
throws CannotCompileException
{
- final CacheKey key = new CacheKey( classLoader, interfaceMethod );
- Class invocationClass = ( Class ) invocationClassCache.get( key );
- if( invocationClass == null )
- {
- log.debug( "Generating method invocation class for method " + interfaceMethod + "..." );
- final CtClass ctClass = JavassistUtils.createClass(
- interfaceMethod.getDeclaringClass().getSimpleName() + "_" + interfaceMethod.getName() +
- "_invocation",
- JavassistMethodInvocation.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 " );
- }
- else
- {
- proceedBody.append( "\t" );
- }
- proceedBody.append( "( (" );
- proceedBody.append( interfaceMethod.getDeclaringClass().getName() );
- proceedBody.append( " )target )." );
- proceedBody.append( interfaceMethod.getName() );
- proceedBody.append( "(" );
- for( int i = 0; i < argumentTypes.length; ++i )
+ 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 )
{
- proceedBody.append( "(" );
- proceedBody.append( argumentTypes[i].getName() );
- proceedBody.append( ")arguments[" );
- proceedBody.append( i );
- proceedBody.append( "]" );
- if( i != argumentTypes.length - 1 )
+ invocationClass = invocationClassRef.get();
+ if( invocationClass == null )
{
- proceedBody.append( ", " );
+ invocationClass = createInvocationClass( classLoader, interfaceMethod );
+ classCache.put( key, new WeakReference<Class>( invocationClass ) );
}
}
- proceedBody.append( ");\n" );
- if( Void.TYPE.equals( interfaceMethod.getReturnType() ) )
- {
- proceedBody.append( "\treturn null;\n" );
- }
- proceedBody.append( "}" );
- proceedMethod.setBody( proceedBody.toString() );
- ctClass.addMethod( proceedMethod );
- invocationClass = ctClass.toClass( classLoader );
- invocationClassCache.put( key, invocationClass );
}
return invocationClass;
}
- private static class CacheKey
+ private static Class createInvocationClass( ClassLoader classLoader, Method interfaceMethod )
+ throws CannotCompileException
{
- private final ClassLoader classLoader;
- private final Method method;
-
- public CacheKey( ClassLoader classLoader, Method method )
+ Class invocationClass;
+ final CtClass ctClass = JavassistUtils.createClass(
+ interfaceMethod.getDeclaringClass().getSimpleName() + "_" + interfaceMethod.getName() +
+ "_invocation",
+ JavassistMethodInvocation.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() ) )
{
- this.classLoader = classLoader;
- this.method = method;
+ proceedBody.append( "\treturn " );
}
-
- public boolean equals( Object o )
+ else
{
- if( this == o )
- {
- return true;
- }
- if( o == null || getClass() != o.getClass() )
- {
- return false;
- }
- final CacheKey cacheKey = ( CacheKey ) o;
- if( !classLoader.equals( cacheKey.classLoader ) )
- {
- return false;
- }
- if( !method.equals( cacheKey.method ) )
+ proceedBody.append( "\t" );
+ }
+ proceedBody.append( "( (" );
+ proceedBody.append( interfaceMethod.getDeclaringClass().getName() );
+ proceedBody.append( " )target )." );
+ proceedBody.append( interfaceMethod.getName() );
+ proceedBody.append( "(" );
+ for( int i = 0; i < argumentTypes.length; ++i )
+ {
+ proceedBody.append( "(" );
+ proceedBody.append( argumentTypes[i].getName() );
+ proceedBody.append( ")arguments[" );
+ proceedBody.append( i );
+ proceedBody.append( "]" );
+ if( i != argumentTypes.length - 1 )
{
- return false;
+ proceedBody.append( ", " );
}
- return true;
}
-
- public int hashCode()
+ proceedBody.append( ");\n" );
+ if( Void.TYPE.equals( interfaceMethod.getReturnType() ) )
{
- int result;
- result = classLoader.hashCode();
- result = 29 * result + method.hashCode();
- return result;
+ proceedBody.append( "\treturn null;\n" );
}
+ proceedBody.append( "}" );
+ proceedMethod.setBody( proceedBody.toString() );
+ ctClass.addMethod( proceedMethod );
+ invocationClass = ctClass.toClass( classLoader );
+ return invocationClass;
}
}
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=265645&r1=265644&r2=265645&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 Wed Aug 31 21:19:02 2005
@@ -23,13 +23,11 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.apache.commons.proxy.ObjectProvider;
import org.apache.commons.proxy.exception.ProxyFactoryException;
-import org.apache.commons.proxy.factory.AbstractProxyFactory;
+import org.apache.commons.proxy.factory.util.AbstractProxyClassGenerator;
+import org.apache.commons.proxy.factory.util.AbstractProxyFactory;
+import org.apache.commons.proxy.factory.util.ProxyClassCache;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
/**
* A <a href="http://www.jboss.org/products/javassist">Javassist</a>-based {@link org.apache.commons.proxy.ProxyFactory}
@@ -40,182 +38,116 @@
*/
public class JavassistProxyFactory extends AbstractProxyFactory
{
- // TODO: Make sure this doesn't cause memory leaks in application servers!
- private static HashMap<ProxyClassDescriptor, Class> delegatingProxyClassCache = new HashMap<ProxyClassDescriptor, Class>();
- // TODO: Make sure this doesn't cause memory leaks in application servers!
- private static HashMap<ProxyClassDescriptor, Class> interceptingProxyClassCache = new HashMap<ProxyClassDescriptor, Class>();
+ private static final ProxyClassCache delegatingProxyClassCache = new ProxyClassCache(
+ new DelegatingProxyClassGenerator() );
+ private static final ProxyClassCache interceptingProxyClassCache = new ProxyClassCache(
+ new InterceptingProxyClassGenerator() );
public Object createInterceptingProxy( ClassLoader classLoader, Object target, MethodInterceptor interceptor,
Class... proxyInterfaces )
{
- synchronized( interceptingProxyClassCache )
+ try
{
- final Method[] methods = getImplementationMethods( proxyInterfaces );
- final ProxyClassDescriptor key = new ProxyClassDescriptor( methods, classLoader );
- Class clazz = interceptingProxyClassCache.get( key );
- if( clazz == null )
- {
- log.debug( "Generating intercepting proxy class for interfaces " + Arrays.asList( proxyInterfaces ) +
- " using class loader " + classLoader + "..." );
- try
- {
- final CtClass proxyClass = JavassistUtils.createClass();
- JavassistUtils.addInterfaces( proxyClass, proxyInterfaces );
- JavassistUtils.addField( Method[].class, "methods", proxyClass );
- JavassistUtils.addField( Object.class, "target", proxyClass );
- JavassistUtils.addField( MethodInterceptor.class, "interceptor", proxyClass );
- final CtConstructor proxyConstructor = new CtConstructor(
- JavassistUtils.resolve(
- new Class[]{Method[].class, Object.class, MethodInterceptor.class} ),
- proxyClass );
- proxyConstructor
- .setBody( "{\n\tthis.methods = $1;\n\tthis.target = $2;\n\tthis.interceptor = $3; }" );
- proxyClass.addConstructor( proxyConstructor );
- for( int i = 0; i < methods.length; ++i )
- {
- final CtMethod method = new CtMethod( JavassistUtils.resolve( methods[i].getReturnType() ),
- methods[i].getName(),
- JavassistUtils.resolve( methods[i].getParameterTypes() ),
- proxyClass );
- final Class invocationClass = JavassistMethodInvocation
- .getMethodInvocationClass( classLoader, methods[i] );
- final String body = "{\n\t return ( $r ) interceptor.invoke( new " + invocationClass.getName() +
- "( methods[" + i + "], target, $args ) );\n }";
- method.setBody( body );
- proxyClass.addMethod( method );
- }
- clazz = proxyClass.toClass( classLoader );
- interceptingProxyClassCache.put( key, clazz );
- }
- catch( CannotCompileException e )
- {
- throw new ProxyFactoryException( "Could not compile class.", e );
- }
- }
- try
- {
- return clazz.getConstructor( Method[].class, Object.class, MethodInterceptor.class )
- .newInstance( methods, target, interceptor );
- }
- catch( Exception e )
- {
- throw new ProxyFactoryException( "Unable to instantiate proxy class instance.", e );
+ final Class clazz = interceptingProxyClassCache.getProxyClass( classLoader, proxyInterfaces );
+ final Method[] methods = AbstractProxyClassGenerator.getImplementationMethods( proxyInterfaces );
+ return clazz.getConstructor( Method[].class, Object.class, MethodInterceptor.class )
+ .newInstance( methods, target, interceptor );
+ }
+ catch( Exception e )
+ {
+ throw new ProxyFactoryException( "Unable to instantiate proxy class instance.", e );
- }
}
}
public Object createDelegatingProxy( ClassLoader classLoader, ObjectProvider targetProvider,
Class... proxyInterfaces )
{
- synchronized( delegatingProxyClassCache )
+ try
{
- final Method[] methods = getImplementationMethods( proxyInterfaces );
- final ProxyClassDescriptor key = new ProxyClassDescriptor( methods, classLoader );
- Class clazz = delegatingProxyClassCache.get( key );
- if( clazz == null )
- {
- log.debug( "Generating delegating proxy class for interfaces " + Arrays.asList( proxyInterfaces ) +
- " using class loader " + classLoader + "..." );
- try
- {
- final CtClass proxyClass = JavassistUtils.createClass();
- 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 );
- addMethods( proxyInterfaces, proxyClass, new DelegatingMethodBodyProvider() );
- clazz = proxyClass.toClass( classLoader );
- delegatingProxyClassCache.put( key, clazz );
- }
- catch( CannotCompileException e )
- {
- throw new ProxyFactoryException( "Could not compile class.", e );
- }
- }
- try
- {
- return clazz.getConstructor( ObjectProvider.class ).newInstance( targetProvider );
- }
- catch( Exception e )
- {
- throw new ProxyFactoryException( "Unable to instantiate proxy from generated proxy class.", e );
- }
- }
- }
-
- private void addMethods( Class[] proxyInterfaces, CtClass proxyClass, MethodBodyProvider methodBodyProvider )
- throws CannotCompileException
- {
- JavassistUtils.addInterfaces( proxyClass, proxyInterfaces );
- final Method[] methods = getImplementationMethods( proxyInterfaces );
- for( int i = 0; i < methods.length; ++i )
- {
- final Method method = methods[i];
- final CtMethod ctMethod = new CtMethod( JavassistUtils.resolve( method.getReturnType() ),
- method.getName(),
- JavassistUtils.resolve( method.getParameterTypes() ),
- proxyClass );
- ctMethod.setBody( methodBodyProvider.getMethodBody( method ) );
- proxyClass.addMethod( ctMethod );
+ final Class clazz = delegatingProxyClassCache.getProxyClass( classLoader, proxyInterfaces );
+ return clazz.getConstructor( ObjectProvider.class ).newInstance( targetProvider );
}
- }
-
- private interface MethodBodyProvider
- {
- public String getMethodBody( Method method );
- }
-
- private class DelegatingMethodBodyProvider implements MethodBodyProvider
- {
- public String getMethodBody( Method method )
+ catch( Exception e )
{
- return "{ return ( $r ) ( ( " + method.getDeclaringClass().getName() + " )provider.getDelegate() )." +
- method.getName() + "($$); }";
+ throw new ProxyFactoryException( "Unable to instantiate proxy from generated proxy class.", e );
}
}
- private static class ProxyClassDescriptor
+ private static class InterceptingProxyClassGenerator extends AbstractProxyClassGenerator
{
- private final List<Method> methods;
- private final ClassLoader classLoader;
-
- public ProxyClassDescriptor( Method[] methods, ClassLoader classLoader )
- {
- this.methods = new ArrayList<Method>( Arrays.asList( methods ) );
- this.classLoader = classLoader;
- }
-
- public boolean equals( Object o )
+ public Class generateProxyClass( ClassLoader classLoader, Class... proxyInterfaces )
{
- if( this == o )
+ try
{
- return true;
+ final CtClass proxyClass = JavassistUtils.createClass();
+ final Method[] methods = getImplementationMethods( proxyInterfaces );
+ JavassistUtils.addInterfaces( proxyClass, proxyInterfaces );
+ JavassistUtils.addField( Method[].class, "methods", proxyClass );
+ JavassistUtils.addField( Object.class, "target", proxyClass );
+ JavassistUtils.addField( MethodInterceptor.class, "interceptor", proxyClass );
+ final CtConstructor proxyConstructor = new CtConstructor(
+ JavassistUtils.resolve(
+ new Class[]{Method[].class, Object.class, MethodInterceptor.class} ),
+ proxyClass );
+ proxyConstructor
+ .setBody( "{\n\tthis.methods = $1;\n\tthis.target = $2;\n\tthis.interceptor = $3; }" );
+ proxyClass.addConstructor( proxyConstructor );
+ for( int i = 0; i < methods.length; ++i )
+ {
+ final CtMethod method = new CtMethod( JavassistUtils.resolve( methods[i].getReturnType() ),
+ methods[i].getName(),
+ JavassistUtils.resolve( methods[i].getParameterTypes() ),
+ proxyClass );
+ final Class invocationClass = JavassistMethodInvocation
+ .getMethodInvocationClass( classLoader, methods[i] );
+ final String body = "{\n\t return ( $r ) interceptor.invoke( new " + invocationClass.getName() +
+ "( methods[" + i + "], target, $args ) );\n }";
+ method.setBody( body );
+ proxyClass.addMethod( method );
+ }
+ return proxyClass.toClass( classLoader );
}
- if( o == null || getClass() != o.getClass() )
+ catch( CannotCompileException e )
{
- return false;
+ throw new ProxyFactoryException( "Could not compile class.", e );
}
- final ProxyClassDescriptor that = ( ProxyClassDescriptor ) o;
- if( classLoader != null ? !classLoader.equals( that.classLoader ) : that.classLoader != null )
+ }
+ }
+
+ private static class DelegatingProxyClassGenerator extends AbstractProxyClassGenerator
+ {
+ public Class generateProxyClass( ClassLoader classLoader, Class... proxyInterfaces )
+ {
+ try
{
- return false;
+ final CtClass proxyClass = JavassistUtils.createClass();
+ 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, proxyInterfaces );
+ final Method[] methods = getImplementationMethods( proxyInterfaces );
+ for( int i = 0; i < methods.length; ++i )
+ {
+ final Method method = methods[i];
+ final CtMethod ctMethod = new CtMethod( JavassistUtils.resolve( method.getReturnType() ),
+ method.getName(),
+ JavassistUtils.resolve( method.getParameterTypes() ),
+ proxyClass );
+ ctMethod.setBody( "{ return ( $r ) ( ( " + method.getDeclaringClass().getName() +
+ " )provider.getDelegate() )." +
+ method.getName() + "($$); }" );
+ proxyClass.addMethod( ctMethod );
+ }
+ return proxyClass.toClass( classLoader );
}
- if( methods != null ? !methods.equals( that.methods ) : that.methods != null )
+ catch( CannotCompileException e )
{
- return false;
+ throw new ProxyFactoryException( "Could not compile class.", e );
}
- return true;
- }
-
- public int hashCode()
- {
- int result;
- result = ( methods != null ? methods.hashCode() : 0 );
- result = 29 * result + ( classLoader != null ? classLoader.hashCode() : 0 );
- return result;
}
}
}
Modified: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/reflect/ReflectionProxyFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/reflect/ReflectionProxyFactory.java?rev=265645&r1=265644&r2=265645&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/reflect/ReflectionProxyFactory.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/reflect/ReflectionProxyFactory.java Wed Aug 31 21:19:02 2005
@@ -18,7 +18,7 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.apache.commons.proxy.ObjectProvider;
-import org.apache.commons.proxy.factory.AbstractProxyFactory;
+import org.apache.commons.proxy.factory.util.AbstractProxyFactory;
import java.lang.reflect.Proxy;
Added: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java?rev=265645&view=auto
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java (added)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java Wed Aug 31 21:19:02 2005
@@ -0,0 +1,52 @@
+/* $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.factory.util;
+
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author James Carman
+ * @version 1.0
+ */
+public abstract class AbstractProxyClassGenerator implements ProxyClassGenerator
+{
+ public static Method[] getImplementationMethods( Class... proxyInterfaces )
+ {
+ final Set<MethodSignature> signatures = new HashSet<MethodSignature>();
+ final List<Method> resultingMethods = new LinkedList<Method>();
+ for( int i = 0; i < proxyInterfaces.length; i++ )
+ {
+ Class proxyInterface = proxyInterfaces[i];
+ final Method[] methods = proxyInterface.getDeclaredMethods();
+ for( int j = 0; j < methods.length; j++ )
+ {
+ final MethodSignature signature = new MethodSignature( methods[j] );
+ if( !signatures.contains( signature ) )
+ {
+ signatures.add( signature );
+ resultingMethods.add( methods[j] );
+ }
+ }
+ }
+ final Method[] results = new Method[resultingMethods.size()];
+ return resultingMethods.toArray( results );
+ }
+}
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyClassGenerator.java
------------------------------------------------------------------------------
svn:keywords = Id
Copied: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java (from r265575, jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/AbstractProxyFactory.java)
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java?p2=jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java&p1=jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/AbstractProxyFactory.java&r1=265575&r2=265645&rev=265645&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/AbstractProxyFactory.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java Wed Aug 31 21:19:02 2005
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.commons.proxy.factory;
+package org.apache.commons.proxy.factory.util;
import org.aopalliance.intercept.MethodInterceptor;
import org.apache.commons.logging.Log;
@@ -57,27 +57,5 @@
public Object createDelegatingProxy( ObjectProvider targetProvider, Class... proxyInterfaces )
{
return createDelegatingProxy( Thread.currentThread().getContextClassLoader(), targetProvider, proxyInterfaces );
- }
-
- protected Method[] getImplementationMethods( Class... proxyInterfaces )
- {
- final Set<MethodSignature> signatures = new HashSet<MethodSignature>();
- final List<Method> resultingMethods = new LinkedList<Method>();
- for( int i = 0; i < proxyInterfaces.length; i++ )
- {
- Class proxyInterface = proxyInterfaces[i];
- final Method[] methods = proxyInterface.getDeclaredMethods();
- for( int j = 0; j < methods.length; j++ )
- {
- final MethodSignature signature = new MethodSignature( methods[j] );
- if( !signatures.contains( signature ) )
- {
- signatures.add( signature );
- resultingMethods.add( methods[j] );
- }
- }
- }
- final Method[] results = new Method[resultingMethods.size()];
- return resultingMethods.toArray( results );
}
}
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/AbstractProxyFactory.java
------------------------------------------------------------------------------
svn:keywords = Id
Copied: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java (from r265575, jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/MethodSignature.java)
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java?p2=jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java&p1=jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/MethodSignature.java&r1=265575&r2=265645&rev=265645&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/MethodSignature.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java Wed Aug 31 21:19:02 2005
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.commons.proxy.factory;
+package org.apache.commons.proxy.factory.util;
import java.lang.reflect.Method;
import java.util.Arrays;
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/MethodSignature.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java?rev=265645&view=auto
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java (added)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java Wed Aug 31 21:19:02 2005
@@ -0,0 +1,89 @@
+/* $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.factory.util;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * @author James Carman
+ * @version 1.0
+ */
+public class ProxyClassCache
+{
+ private final Map<ClassLoader, Map<String, WeakReference<Class>>> loaderToClassCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class>>>();
+ private final ProxyClassGenerator proxyClassGenerator;
+
+ public ProxyClassCache( ProxyClassGenerator proxyClassGenerator )
+ {
+ this.proxyClassGenerator = proxyClassGenerator;
+ }
+
+ public synchronized Class getProxyClass( ClassLoader classLoader, Class... proxyInterfaces )
+ {
+ final Map<String, WeakReference<Class>> classCache = getClassCache( classLoader );
+ final String key = toClassCacheKey( proxyInterfaces );
+ Class proxyClass;
+ WeakReference<Class> proxyClassReference = classCache.get( key );
+ if( proxyClassReference == null )
+ {
+ proxyClass = proxyClassGenerator.generateProxyClass( classLoader, proxyInterfaces );
+ classCache.put( key, new WeakReference<Class>( proxyClass ) );
+ }
+ else
+ {
+ synchronized( proxyClassReference )
+ {
+ proxyClass = proxyClassReference.get();
+ if( proxyClass == null )
+ {
+ proxyClass = proxyClassGenerator.generateProxyClass( classLoader, proxyInterfaces );
+ classCache.put( key, new WeakReference<Class>( proxyClass ) );
+ }
+ }
+ }
+ return proxyClass;
+ }
+
+ private String toClassCacheKey( Class... proxyInterfaces )
+ {
+ final StringBuffer sb = new StringBuffer();
+ for( int i = 0; i < proxyInterfaces.length; i++ )
+ {
+ Class proxyInterface = proxyInterfaces[i];
+ sb.append( proxyInterface.getName() );
+ if( i != proxyInterfaces.length - 1 )
+ {
+ sb.append( "," );
+ }
+ }
+ return sb.toString();
+ }
+
+ private 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;
+ }
+}
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassCache.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java?rev=265645&view=auto
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java (added)
+++ jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java Wed Aug 31 21:19:02 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.factory.util;
+
+/**
+ * @author James Carman
+ * @version 1.0
+ */
+public interface ProxyClassGenerator
+{
+ public Class generateProxyClass( ClassLoader classLoader, Class... proxyInterfaces );
+}
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/proxy/trunk/src/java/org/apache/commons/proxy/factory/util/ProxyClassGenerator.java
------------------------------------------------------------------------------
svn:keywords = Id
Copied: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java (from r265575, jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/TestMethodSignature.java)
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java?p2=jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java&p1=jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/TestMethodSignature.java&r1=265575&r2=265645&rev=265645&view=diff
==============================================================================
--- jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/TestMethodSignature.java (original)
+++ jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java Wed Aug 31 21:19:02 2005
@@ -14,10 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.commons.proxy.factory;
+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;
+import org.apache.commons.proxy.factory.util.MethodSignature;
public class TestMethodSignature extends TestCase
{
Propchange: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/proxy/trunk/src/test/org/apache/commons/proxy/factory/util/TestMethodSignature.java
------------------------------------------------------------------------------
svn:keywords = Id
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org