You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2013/01/01 07:10:28 UTC
svn commit: r1427310 - in /openwebbeans/trunk/webbeans-impl/src:
main/java/org/apache/webbeans/proxy/ main/java/org/apache/webbeans/util/
test/java/org/apache/webbeans/newtests/interceptors/factory/
test/java/org/apache/webbeans/newtests/interceptors/f...
Author: struberg
Date: Tue Jan 1 06:10:27 2013
New Revision: 1427310
URL: http://svn.apache.org/viewvc?rev=1427310&view=rev
Log:
OWB-344 improve return value handling
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
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.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=1427310&r1=1427309&r2=1427310&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 Tue Jan 1 06:10:27 2013
@@ -24,6 +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.List;
import org.apache.webbeans.config.WebBeansContext;
@@ -138,13 +139,15 @@ public class InterceptorDecoratorProxyFa
createConstructor(cw, proxyClassFileName, classToProxy, classFileName);
- delegateNonInterceptedMethods(cw, proxyClassFileName, classToProxy, classFileName, nonInterceptedMethods);
-
-
-
- //X TODO invoke all
+ if (nonInterceptedMethods != null)
+ {
+ delegateNonInterceptedMethods(cw, proxyClassFileName, classToProxy, classFileName, nonInterceptedMethods);
+ }
- //X TODO continue;
+ if (interceptedMethods != null)
+ {
+ delegateInterceptedMethods(cw, proxyClassFileName, classToProxy, classFileName, interceptedMethods);
+ }
return cw.toByteArray();
}
@@ -205,22 +208,31 @@ public class InterceptorDecoratorProxyFa
*
* @param noninterceptedMethods all methods which are neither intercepted nor decorated
*/
- private static void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName,
- List<Method> noninterceptedMethods)
+ private void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName,
+ List<Method> noninterceptedMethods)
{
- for (Method proxiedMethod : noninterceptedMethods)
+ for (Method delegatedMethod : noninterceptedMethods)
{
- String methodDescriptor = Type.getMethodDescriptor(proxiedMethod);
+ int modifiers = delegatedMethod.getModifiers();
+
+ if (unproxyableMethod(delegatedMethod))
+ {
+ continue;
+ }
+
+ String methodDescriptor = Type.getMethodDescriptor(delegatedMethod);
//X TODO handle generic exception types?
- Class[] exceptionTypes = proxiedMethod.getExceptionTypes();
+ Class[] exceptionTypes = delegatedMethod.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);
+ int targetModifiers = delegatedMethod.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC);
+
+ MethodVisitor mv = cw.visitMethod(targetModifiers, delegatedMethod.getName(), methodDescriptor, null, exceptionTypeNames);
// fill method body
mv.visitCode();
@@ -230,18 +242,17 @@ public class InterceptorDecoratorProxyFa
mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, FIELD_PROXIED_INSTANCE, Type.getDescriptor(classToProxy));
int offset = 1;
- for (Class<?> aClass : proxiedMethod.getParameterTypes())
+ for (Class<?> aClass : delegatedMethod.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 declaringClass = Type.getType(delegatedMethod.getDeclaringClass());
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, declaringClass.getInternalName(), delegatedMethod.getName(), methodDescriptor);
- final Type returnType = Type.getType(proxiedMethod.getReturnType());
- mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
+ generateReturn(mv, delegatedMethod);
mv.visitMaxs(-1, -1);
@@ -249,6 +260,81 @@ public class InterceptorDecoratorProxyFa
}
}
+ private boolean unproxyableMethod(Method delegatedMethod)
+ {
+ int modifiers = delegatedMethod.getModifiers();
+
+ //X TODO how to deal with native functions?
+ return (modifiers & (Modifier.PRIVATE | Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.NATIVE)) > 0 ||
+ "finalize".equals(delegatedMethod.getName());
+ }
+
+ private void delegateInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName,
+ List<Method> interceptedMethods)
+ {
+ for (Method proxiedMethod : interceptedMethods)
+ {
+
+ }
+ }
+
+
+ private void generateReturn(MethodVisitor mv, Method delegatedMethod)
+ {
+ final Class<?> returnType = delegatedMethod.getReturnType();
+ mv.visitInsn(getReturnInsn(returnType));
+ }
+
+ /**
+ * Gets the appropriate bytecode instruction for RETURN, according to what type we need to return
+ *
+ * @param type Type the needs to be returned
+ * @return The matching bytecode instruction
+ */
+ private int getReturnInsn(final Class<?> type)
+ {
+ if (type.isPrimitive())
+ {
+ if (Void.TYPE.equals(type))
+ {
+ return Opcodes.RETURN;
+ }
+ if (Integer.TYPE.equals(type))
+ {
+ return Opcodes.IRETURN;
+ }
+ else if (Boolean.TYPE.equals(type))
+ {
+ return Opcodes.IRETURN;
+ }
+ else if (Character.TYPE.equals(type))
+ {
+ return Opcodes.IRETURN;
+ }
+ else if (Byte.TYPE.equals(type))
+ {
+ return Opcodes.IRETURN;
+ }
+ else if (Short.TYPE.equals(type))
+ {
+ return Opcodes.IRETURN;
+ }
+ else if (Float.TYPE.equals(type))
+ {
+ return Opcodes.FRETURN;
+ }
+ else if (Long.TYPE.equals(type))
+ {
+ return Opcodes.LRETURN;
+ }
+ else if (Double.TYPE.equals(type))
+ {
+ return Opcodes.DRETURN;
+ }
+ }
+
+ return Opcodes.ARETURN;
+ }
/**
* The 'defineClass' method on the ClassLoader is protected, thus we need to invoke it via reflection.
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=1427310&r1=1427309&r2=1427310&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 Tue Jan 1 06:10:27 2013
@@ -290,6 +290,7 @@ public final class ClassUtil
{
methods = new ArrayList<Method>();
methods.add(method);
+ allMethods.add(method);
methodMap.put(method.getName(), methods);
}
else
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=1427310&r1=1427309&r2=1427310&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 Tue Jan 1 06:10:27 2013
@@ -20,6 +20,8 @@ package org.apache.webbeans.newtests.int
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -47,14 +49,36 @@ public class InterceptorDecoratorProxyFa
InterceptorDecoratorProxyFactory pf = new InterceptorDecoratorProxyFactory(getWebBeansContext());
- ClassLoader classLoader = this.getClass().getClassLoader();
+ // we take a fresh URLClassLoader to not blur the test classpath with synthetic classes.
+ ClassLoader classLoader = new URLClassLoader(new URL[0]);
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);
+/*X
+ for (Method m : methods)
+ {
+ List<Method> ms = new ArrayList<Method>();
+ ms.add(m);
+
+ try
+ {
+ Class<ClassInterceptedClass> pc = pf.createProxyClass(cl, ClassInterceptedClass.class, null, ms);
+ Assert.assertNotNull(pc);
+ }
+ catch (Exception e)
+ {
+ System.out.println("hab die sau :) " + m.toString());
+ }
+ }
+*/
+
+ ClassInterceptedClass internalInstance = new ClassInterceptedClass();
+ internalInstance.init();
+
+ ClassInterceptedClass proxy = pf.createProxyInstance(proxyClass, internalInstance, null);
Assert.assertNotNull(proxy);
// we need to get the field from the proxy via reflection
@@ -69,7 +93,9 @@ public class InterceptorDecoratorProxyFa
proxy.setMeaningOfLife(42);
Assert.assertEquals(42, proxy.getMeaningOfLife());
-
+ Assert.assertEquals(internalInstance.getFloat(), proxy.getFloat(), 0f);
+ Assert.assertEquals('c', proxy.getChar());
+ Assert.assertEquals(internalInstance, proxy.getSelf());
shutDownContainer();
}
Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java?rev=1427310&r1=1427309&r2=1427310&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java Tue Jan 1 06:10:27 2013
@@ -29,12 +29,20 @@ public class ClassInterceptedClass
private boolean defaultCtInvoked = false;
private int meaningOfLife;
+ private float f;
+ private char c;
public ClassInterceptedClass()
{
defaultCtInvoked = true;
}
+ public void init()
+ {
+ f = 2.4f;
+ c = 'c';
+ }
+
public int getMeaningOfLife()
{
System.out.println("answering the question about life, the universe and everything!");
@@ -47,4 +55,19 @@ public class ClassInterceptedClass
this.meaningOfLife = meaningOfLife;
}
+ public float getFloat()
+ {
+ return f;
+ }
+
+ public ClassInterceptedClass getSelf()
+ {
+ return this;
+ }
+
+ public char getChar()
+ {
+ return c;
+ }
+
}