commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jcar...@apache.org
Subject 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...
Date Thu, 15 Jul 2010 23:10:46 GMT
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>



Mime
View raw message