You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jc...@apache.org on 2010/07/16 01:10:46 UTC
svn commit: r964636 [3/3] - in
/commons/proper/proxy/branches/version-2.0-work: ./ cglib/ cglib/src/
cglib/src/main/ cglib/src/main/java/ cglib/src/main/java/org/
cglib/src/main/java/org/apache/ cglib/src/main/java/org/apache/commons/
cglib/src/main/ja...
Added: commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/QuoteService.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/QuoteService.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/QuoteService.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/QuoteService.java Thu Jul 15 23:10:43 2010
@@ -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.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;
+}
Added: commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/core/src/test/java/org/apache/commons/proxy/util/SuffixInterceptor.java Thu Jul 15 23:10:43 2010
@@ -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.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;
+ }
+}
Added: commons/proper/proxy/branches/version-2.0-work/javassist/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/javassist/pom.xml?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/javassist/pom.xml (added)
+++ commons/proper/proxy/branches/version-2.0-work/javassist/pom.xml Thu Jul 15 23:10:43 2010
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-proxy</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy-javassist</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistInvocation.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistInvocation.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistInvocation.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistInvocation.java Thu Jul 15 23:10:43 2010
@@ -0,0 +1,222 @@
+/*
+ * 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.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;
+ }
+}
Added: commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistProxyFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistProxyFactory.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistProxyFactory.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistProxyFactory.java Thu Jul 15 23:10:43 2010
@@ -0,0 +1,255 @@
+package org.apache.commons.proxy.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.impl.AbstractProxyClassGenerator;
+import org.apache.commons.proxy.impl.AbstractSubclassingProxyFactory;
+import org.apache.commons.proxy.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 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(ObjectProvider.class)
+ .newInstance(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(Object.class, Interceptor.class)
+ .newInstance(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(Invoker.class)
+ .newInstance(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);
+ }
+ }
+ }
+}
Added: commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistUtils.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistUtils.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/javassist/src/main/java/org/apache/commons/proxy/javassist/JavassistUtils.java Thu Jul 15 23:10:43 2010
@@ -0,0 +1,154 @@
+/*
+ * 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.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;
+ }
+}
Added: commons/proper/proxy/branches/version-2.0-work/javassist/src/test/java/org/apache/commons/proxy/javassist/TestJavassistProxyFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/javassist/src/test/java/org/apache/commons/proxy/javassist/TestJavassistProxyFactory.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/javassist/src/test/java/org/apache/commons/proxy/javassist/TestJavassistProxyFactory.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/javassist/src/test/java/org/apache/commons/proxy/javassist/TestJavassistProxyFactory.java Thu Jul 15 23:10:43 2010
@@ -0,0 +1,16 @@
+package org.apache.commons.proxy.javassist;
+
+import org.apache.commons.proxy.AbstractSubclassingProxyFactoryTestCase;
+import org.apache.commons.proxy.ProxyFactory;
+
+public class TestJavassistProxyFactory extends AbstractSubclassingProxyFactoryTestCase
+{
+//**********************************************************************************************************************
+// Constructors
+//**********************************************************************************************************************
+
+ public TestJavassistProxyFactory()
+ {
+ super(new JavassistProxyFactory());
+ }
+}
Added: commons/proper/proxy/branches/version-2.0-work/jdk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/jdk/pom.xml?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/jdk/pom.xml (added)
+++ commons/proper/proxy/branches/version-2.0-work/jdk/pom.xml Thu Jul 15 23:10:43 2010
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-proxy</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>commons-proxy-jdk</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons-proxy-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: commons/proper/proxy/branches/version-2.0-work/jdk/src/main/java/org/apache/commons/proxy/jdk/JdkProxyFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/jdk/src/main/java/org/apache/commons/proxy/jdk/JdkProxyFactory.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/jdk/src/main/java/org/apache/commons/proxy/jdk/JdkProxyFactory.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/jdk/src/main/java/org/apache/commons/proxy/jdk/JdkProxyFactory.java Thu Jul 15 23:10:43 2010
@@ -0,0 +1,190 @@
+package org.apache.commons.proxy.jdk;
+
+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.ProxyUtils;
+import org.apache.commons.proxy.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;
+
+public class JdkProxyFactory extends AbstractProxyFactory
+{
+//**********************************************************************************************************************
+// ProxyFactory Implementation
+//**********************************************************************************************************************
+
+
+ /**
+ * 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.
+ *
+ * @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.
+ *
+ * @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 abstract static class AbstractInvocationHandler implements InvocationHandler, Serializable
+ {
+ public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
+ {
+ if( isHashCode(method) )
+ {
+ return System.identityHashCode(proxy);
+ }
+ else if( 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
+ {
+ 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 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);
+ }
+ }
+
+ 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();
+ }
+ }
+ }
+}
Added: commons/proper/proxy/branches/version-2.0-work/jdk/src/test/java/org/apache/commons/proxy/jdk/TestJdkProxyFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/jdk/src/test/java/org/apache/commons/proxy/jdk/TestJdkProxyFactory.java?rev=964636&view=auto
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/jdk/src/test/java/org/apache/commons/proxy/jdk/TestJdkProxyFactory.java (added)
+++ commons/proper/proxy/branches/version-2.0-work/jdk/src/test/java/org/apache/commons/proxy/jdk/TestJdkProxyFactory.java Thu Jul 15 23:10:43 2010
@@ -0,0 +1,12 @@
+package org.apache.commons.proxy.jdk;
+
+import org.apache.commons.proxy.AbstractProxyFactoryTestCase;
+import org.apache.commons.proxy.AbstractSubclassingProxyFactoryTestCase;
+
+public class TestJdkProxyFactory extends AbstractProxyFactoryTestCase
+{
+ public TestJdkProxyFactory()
+ {
+ super(new JdkProxyFactory());
+ }
+}
Modified: commons/proper/proxy/branches/version-2.0-work/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/proxy/branches/version-2.0-work/pom.xml?rev=964636&r1=964635&r2=964636&view=diff
==============================================================================
--- commons/proper/proxy/branches/version-2.0-work/pom.xml (original)
+++ commons/proper/proxy/branches/version-2.0-work/pom.xml Thu Jul 15 23:10:43 2010
@@ -20,6 +20,13 @@
<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>javassist</module>
+ <module>cglib</module>
+ </modules>
<parent>
<groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId>
@@ -81,7 +88,6 @@
<roles>
<role>advisor</role>
</roles>
- <url></url>
</contributor>
<contributor>
<name>Howard M. Lewis Ship</name>
@@ -115,93 +121,6 @@
</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.0,)</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>