Author: struberg
Date: Mon Dec 31 19:58:18 2012
New Revision: 1427235

URL: http://svn.apache.org/viewvc?rev=1427235&view=rev
Log:
OWB-344 move method resolving out of the proxy creation


Modified:
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
    
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java?rev=1427235&r1=1427234&r2=1427235&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
 Mon Dec 31 19:58:18 2012
@@ -24,12 +24,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.webbeans.config.WebBeansContext;
 import org.objectweb.asm.ClassWriter;
@@ -143,12 +138,7 @@ public class InterceptorDecoratorProxyFa
         createConstructor(cw, proxyClassFileName, classToProxy, classFileName);
 
 
-        //X TODO filter out clone() and handle it seperately?
-        Map<String, List<Method>> methodMap = 
getNonPrivateMethods(classToProxy);
-
-        //X TODO select all non-intercepted and non-decorated methods
-
-        delegateNonInterceptedMethods(cw, proxyClassFileName, classToProxy, 
classFileName, methodMap);
+        delegateNonInterceptedMethods(cw, proxyClassFileName, classToProxy, 
classFileName, nonInterceptedMethods);
 
 
 
@@ -210,126 +200,52 @@ public class InterceptorDecoratorProxyFa
         }
     }
 
-
     /**
-     * @deprecated move this method to some other place. The proxy should get 
the list of methods from outside.
-     *             Otherwise we would drag in business logic into the purely 
technical interceptor code.
+     * Directly delegate all non intercepted nor decorated methods to the 
internal instance.
+     *
+     * @param noninterceptedMethods all methods which are neither intercepted 
nor decorated
      */
-    private Map<String, List<Method>> getNonPrivateMethods(Class<?> clazz)
+    private static void delegateNonInterceptedMethods(ClassWriter cw, String 
proxyClassFileName, Class<?> classToProxy, String classFileName,
+                                                      List<Method> 
noninterceptedMethods)
     {
-        Map<String, List<Method>> methodMap = new HashMap<String, 
List<Method>>();
-
-        while (clazz != null)
+        for (Method proxiedMethod : noninterceptedMethods)
         {
-            for (Method method : clazz.getDeclaredMethods())
-            {
-                final int modifiers = method.getModifiers();
+            String methodDescriptor = Type.getMethodDescriptor(proxiedMethod);
 
-                if (Modifier.isFinal(modifiers) || 
Modifier.isPrivate(modifiers) ||
-                    Modifier.isStatic(modifiers) || 
Modifier.isAbstract(modifiers) ||
-                    Modifier.isNative(modifiers)) //X TODO deal with proxying 
native methods (clone) later
-                {
-                    continue;
-                }
-
-                if ("finalize".equals(method.getName()))
-                {
-                    // we do not proxy finalize()
-                    continue;
-                }
-
-                List<Method> methods = methodMap.get(method.getName());
-                if (methods == null)
-                {
-                    methods = new ArrayList<Method>();
-                    methods.add(method);
-                    methodMap.put(method.getName(), methods);
-                }
-                else
-                {
-                    if (isOverridden(methods, method))
-                    {
-                        // method is overridden in superclass, so do nothing
-                    }
-                    else
-                    {
-                        // method is not overridden, so add it
-                        methods.add(method);
-                    }
-                }
+            //X TODO handle generic exception types?
+            Class[] exceptionTypes = proxiedMethod.getExceptionTypes();
+            String[] exceptionTypeNames = new String[exceptionTypes.length];
+            for (int i = 0; i < exceptionTypes.length; i++)
+            {
+                exceptionTypeNames[i] = 
Type.getType(exceptionTypes[i]).getInternalName();
             }
 
-            clazz = clazz.getSuperclass();
-        }
+            MethodVisitor mv = cw.visitMethod(proxiedMethod.getModifiers(), 
proxiedMethod.getName(), methodDescriptor, null, exceptionTypeNames);
 
-        return methodMap;
-    }
+            // fill method body
+            mv.visitCode();
 
-    /**
-     * @deprecated see explanation in {@link #getNonPrivateMethods(Class)}
-     */
-    private boolean isOverridden(final List<Method> methods, final Method 
method)
-    {
-        for (final Method m : methods)
-        {
-            if (Arrays.equals(m.getParameterTypes(), 
method.getParameterTypes()))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
+            // load the delegate variable
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, 
FIELD_PROXIED_INSTANCE, Type.getDescriptor(classToProxy));
 
-    /**
-     * Directly delegate all non intercepted nor decorated methods to the 
internal instance.
-     *
-     * @param noninterceptedMethods all methods which are neither intercepted 
nor decorated
-     */
-    private static void delegateNonInterceptedMethods(ClassWriter cw, String 
proxyClassFileName, Class<?> classToProxy, String classFileName,
-                                                      Map<String, 
List<Method>> noninterceptedMethods)
-    {
-        for (List<Method> methodsPerName : noninterceptedMethods.values())
-        {
-            for (Method proxiedMethod : methodsPerName)
+            int offset = 1;
+            for (Class<?> aClass : proxiedMethod.getParameterTypes())
             {
-                String methodDescriptor = 
Type.getMethodDescriptor(proxiedMethod);
-
-                //X TODO handle generic exception types?
-                Class[] exceptionTypes = proxiedMethod.getExceptionTypes();
-                String[] exceptionTypeNames = new 
String[exceptionTypes.length];
-                for (int i = 0; i < exceptionTypes.length; i++)
-                {
-                    exceptionTypeNames[i] = 
Type.getType(exceptionTypes[i]).getInternalName();
-                }
-
-                MethodVisitor mv = 
cw.visitMethod(proxiedMethod.getModifiers(), proxiedMethod.getName(), 
methodDescriptor, null, exceptionTypeNames);
-
-                // fill method body
-                mv.visitCode();
-
-                // load the delegate variable
-                mv.visitVarInsn(Opcodes.ALOAD, 0);
-                mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, 
FIELD_PROXIED_INSTANCE, Type.getDescriptor(classToProxy));
-
-                int offset = 1;
-                for (Class<?> aClass : proxiedMethod.getParameterTypes())
-                {
-                    final Type type = Type.getType(aClass);
-                    mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), offset);
-                    offset += type.getSize();
-                }
-
-                final Type declaringClass = 
Type.getType(proxiedMethod.getDeclaringClass());
-                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, 
declaringClass.getInternalName(), proxiedMethod.getName(), methodDescriptor);
+                final Type type = Type.getType(aClass);
+                mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), offset);
+                offset += type.getSize();
+            }
 
-                final Type returnType = 
Type.getType(proxiedMethod.getReturnType());
-                mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
+            final Type declaringClass = 
Type.getType(proxiedMethod.getDeclaringClass());
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, 
declaringClass.getInternalName(), proxiedMethod.getName(), methodDescriptor);
 
-                mv.visitMaxs(-1, -1);
+            final Type returnType = 
Type.getType(proxiedMethod.getReturnType());
+            mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
 
-                mv.visitEnd();
+            mv.visitMaxs(-1, -1);
 
-            }
+            mv.visitEnd();
         }
     }
 

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java?rev=1427235&r1=1427234&r2=1427235&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
 Mon Dec 31 19:58:18 2012
@@ -253,6 +253,83 @@ public final class ClassUtil
     }
     private static volatile Set<String> objectMethodNames= null;
 
+    /**
+     * collect all non-private, non-static and non-abstract methods from the 
given class.
+     * This method removes any overloaded methods from the list automatically.
+     *
+     * The returned Map contains the methods divided by the methodName as key 
in the map
+     * following all the methods with the same methodName in a List.
+     *
+     * Note: we filter out the {@link Object#finalize()} method as users must 
not deal with it
+     */
+    public static List<Method> getNonPrivateMethods(Class<?> clazz)
+    {
+        Map<String, List<Method>> methodMap = new HashMap<String, 
List<Method>>();
+        List<Method> allMethods = new ArrayList<Method>(10);
+
+        while (clazz != null)
+        {
+            for (Method method : clazz.getDeclaredMethods())
+            {
+                final int modifiers = method.getModifiers();
+
+                if (Modifier.isFinal(modifiers) || 
Modifier.isPrivate(modifiers) ||
+                    Modifier.isStatic(modifiers) || 
Modifier.isAbstract(modifiers))
+                {
+                    continue;
+                }
+
+                if ("finalize".equals(method.getName()))
+                {
+                    // we do not proxy finalize()
+                    continue;
+                }
+
+                List<Method> methods = methodMap.get(method.getName());
+                if (methods == null)
+                {
+                    methods = new ArrayList<Method>();
+                    methods.add(method);
+                    methodMap.put(method.getName(), methods);
+                }
+                else
+                {
+                    if (isOverridden(methods, method))
+                    {
+                        // method is overridden in superclass, so do nothing
+                    }
+                    else
+                    {
+                        // method is not overridden, so add it
+                        methods.add(method);
+                        allMethods.add(method);
+                    }
+                }
+            }
+
+            clazz = clazz.getSuperclass();
+        }
+
+        return allMethods;
+    }
+
+    /**
+     * Check if the method is already defined in a subclass
+     * @param methods
+     * @param method
+     */
+    private static boolean isOverridden(final List<Method> methods, final 
Method method)
+    {
+        for (final Method m : methods)
+        {
+            if (Arrays.equals(m.getParameterTypes(), 
method.getParameterTypes()))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
 
     /**
      * Checks if the given method if from Object.class
@@ -1148,7 +1225,7 @@ public final class ClassUtil
     }
 
     /**
-     * Learn whether <code>superClassMethod</code> is overridden by 
<code>subClassMethod</code>.
+     * Check whether <code>superClassMethod</code> is overridden by 
<code>subClassMethod</code>.
      * @param subClassMethod potentially overriding
      * @param superClassMethod potentially overridden
      * @return true if overridden

Modified: 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java?rev=1427235&r1=1427234&r2=1427235&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java
 Mon Dec 31 19:58:18 2012
@@ -19,13 +19,16 @@
 package org.apache.webbeans.newtests.interceptors.factory;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.webbeans.newtests.AbstractUnitTest;
 import 
org.apache.webbeans.newtests.interceptors.factory.beans.ClassInterceptedClass;
 import org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory;
 
+import org.apache.webbeans.util.ClassUtil;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -46,7 +49,9 @@ public class InterceptorDecoratorProxyFa
 
         ClassLoader classLoader = this.getClass().getClassLoader();
 
-        Class<ClassInterceptedClass> proxyClass = 
pf.createProxyClass(classLoader, ClassInterceptedClass.class, null, null);
+        List<Method> methods = 
ClassUtil.getNonPrivateMethods(ClassInterceptedClass.class);
+
+        Class<ClassInterceptedClass> proxyClass = 
pf.createProxyClass(classLoader, ClassInterceptedClass.class, null, methods);
         Assert.assertNotNull(proxyClass);
 
         ClassInterceptedClass proxy = pf.createProxyInstance(proxyClass, new 
ClassInterceptedClass(), null);


Reply via email to