You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jg...@apache.org on 2010/02/13 15:50:45 UTC
svn commit: r909833 - in /openejb/trunk/openejb3/container/openejb-core/src:
main/java/org/apache/openejb/util/proxy/
test/java/org/apache/openejb/util/proxy/
Author: jgallimore
Date: Sat Feb 13 14:50:44 2010
New Revision: 909833
URL: http://svn.apache.org/viewvc?rev=909833&view=rev
Log:
OPENEJB-1188 Adding @LocalBean proxy generation code
Added:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGenerator.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/ProxyGenerationException.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImplTest.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestException.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestObject.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/SampleLocalBean.java
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGenerator.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGenerator.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGenerator.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGenerator.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,7 @@
+package org.apache.openejb.util.proxy;
+
+public interface LocalBeanProxyGenerator {
+ public byte[] generateProxy(Class<?> clsToProxy) throws ProxyGenerationException;
+
+ public byte[] generateProxy(Class<?> clsToProxy, String targetClassName) throws ProxyGenerationException;
+}
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,527 @@
+/**
+ * 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.openejb.util.proxy;
+
+import java.lang.reflect.Method;
+
+import org.apache.xbean.asm.ClassWriter;
+import org.apache.xbean.asm.FieldVisitor;
+import org.apache.xbean.asm.Label;
+import org.apache.xbean.asm.MethodVisitor;
+import org.apache.xbean.asm.Opcodes;
+import org.apache.xbean.asm.Type;
+
+
+public class LocalBeanProxyGeneratorImpl implements LocalBeanProxyGenerator, Opcodes {
+
+ private static Object nextUniqueNumberLock = new Object();
+ private final static String proxyClassNamePrefix = "$LocalBeanProxy";
+ private static long nextUniqueNumber = 0;
+
+ private String generateProxyName() {
+ long num;
+ synchronized (nextUniqueNumberLock) {
+ num = nextUniqueNumber++;
+ }
+
+ return proxyClassNamePrefix + num;
+ }
+
+ public byte[] generateProxy(Class<?> clsToProxy) throws ProxyGenerationException {
+ String proxyName = generateProxyName();
+ return generateProxy(clsToProxy, proxyName);
+ }
+
+ public byte[] generateProxy(Class<?> clsToProxy, String proxyName) throws ProxyGenerationException {
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ FieldVisitor fv;
+ MethodVisitor mv;
+
+ String clsToOverride = clsToProxy.getCanonicalName().replace('.', '/');
+
+ // push class signature
+ cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, proxyName, null, clsToOverride, null);
+ cw.visitSource(proxyName + ".java", null);
+
+ // push InvocationHandler field
+ fv = cw.visitField(ACC_FINAL + ACC_PRIVATE, "invocationHandler", "Ljava/lang/reflect/InvocationHandler;", null, null);
+ fv.visitEnd();
+
+ // push constructor
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, clsToOverride, "<init>", "()V");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitFieldInsn(PUTFIELD, proxyName, "invocationHandler", "Ljava/lang/reflect/InvocationHandler;");
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ // loop through public methods, and push something to the class
+ Method[] methods = clsToProxy.getDeclaredMethods();
+ for (Method method : methods) {
+ processMethod(cw, method, proxyName);
+ }
+
+ byte[] clsBytes = cw.toByteArray();
+ return clsBytes;
+ }
+
+
+ private void processMethod(ClassWriter cw, Method method, String proxyName) throws ProxyGenerationException {
+ if ("<init>".equals(method.getName())) {
+ return;
+ }
+
+ Class<?> returnType = method.getReturnType();
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ Class<?>[] exceptionTypes = method.getExceptionTypes();
+
+ // push the method definition
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, method.getName(), getMethodSignatureAsString(returnType, parameterTypes), null, null);
+ mv.visitCode();
+
+ // push try/catch block, to catch declared exceptions, and to catch java.lang.Throwable
+ Label l0 = new Label();
+ Label l1 = new Label();
+ Label l2 = new Label();
+ Label l3 = new Label();
+
+ if (exceptionTypes.length > 0) {
+ mv.visitTryCatchBlock(l0, l1, l2, "java/lang/reflect/InvocationTargetException");
+ }
+
+ mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
+
+ // push try code
+ mv.visitLabel(l0);
+ mv.visitLdcInsn(Type.getType("L" + proxyName + ";"));
+
+ // the following code generates the bytecode for this line of Java:
+ // Method method = <proxy>.class.getMethod("add", new Class[] { <array of function argument classes> });
+
+ // get the method name to invoke, and push to stack
+ mv.visitLdcInsn(method.getName());
+
+ // create the Class[]
+ createArrayDefinition(mv, parameterTypes.length, Class.class);
+
+ int length = 1;
+
+ // push parameters into array
+ for (int i = 0; i < parameterTypes.length; i++) {
+ // keep copy of array on stack
+ mv.visitInsn(DUP);
+
+ Class<?> parameterType = parameterTypes[i];
+
+ // push number onto stack
+ pushIntOntoStack(mv, i);
+
+ if (parameterType.isPrimitive()) {
+ String wrapperType = getWrapperType(parameterType);
+ mv.visitFieldInsn(GETSTATIC, wrapperType, "TYPE", "Ljava/lang/Class;");
+ } else {
+ mv.visitLdcInsn(Type.getType(getAsmTypeAsString(parameterType, true)));
+ }
+
+ mv.visitInsn(AASTORE);
+
+ if (Long.TYPE.equals(parameterType) || Double.TYPE.equals(parameterType)) {
+ length += 2;
+ } else {
+ length++;
+ }
+ }
+
+ // invoke getMethod() with the method name and the array of types
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
+
+ // store the returned method for later
+ mv.visitVarInsn(ASTORE, length);
+
+ // the following code generates bytecode equivalent to:
+ // return ((<returntype>) invocationHandler.invoke(this, method, new Object[] { <function arguments }))[.<primitive>Value()];
+
+ Label l4 = new Label();
+ mv.visitLabel(l4);
+ mv.visitVarInsn(ALOAD, 0);
+
+ // get the invocationHandler field from this class
+ mv.visitFieldInsn(GETFIELD, proxyName, "invocationHandler", "Ljava/lang/reflect/InvocationHandler;");
+
+ // we want to pass "this" in as the first parameter
+ mv.visitVarInsn(ALOAD, 0);
+
+ // and the method we fetched earlier
+ mv.visitVarInsn(ALOAD, length);
+
+ // need to construct the array of objects passed in
+
+ // create the Object[]
+ createArrayDefinition(mv, parameterTypes.length, Object.class);
+
+ int index = 1;
+ // push parameters into array
+ for (int i = 0; i < parameterTypes.length; i++) {
+ // keep copy of array on stack
+ mv.visitInsn(DUP);
+
+ Class<?> parameterType = parameterTypes[i];
+
+ // push number onto stack
+ pushIntOntoStack(mv, i);
+
+ if (parameterType.isPrimitive()) {
+ String wrapperType = getWrapperType(parameterType);
+ mv.visitVarInsn(getVarInsn(parameterType), index);
+
+ mv.visitMethodInsn(INVOKESTATIC, wrapperType, "valueOf", "(" + getPrimitiveLetter(parameterType) + ")L" + wrapperType + ";");
+ mv.visitInsn(AASTORE);
+
+ if (Long.TYPE.equals(parameterType) || Double.TYPE.equals(parameterType)) {
+ index += 2;
+ } else {
+ index++;
+ }
+ } else {
+ mv.visitVarInsn(ALOAD, index);
+ mv.visitInsn(AASTORE);
+ index++;
+ }
+ }
+
+ // invoke the invocationHandler
+ mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
+
+ // cast the result
+ mv.visitTypeInsn(CHECKCAST, getCastType(returnType));
+
+ if (returnType.isPrimitive() && (!Void.TYPE.equals(returnType))) {
+ // get the primitive value
+ mv.visitMethodInsn(INVOKEVIRTUAL, getWrapperType(returnType), getPrimitiveMethod(returnType), "()" + getPrimitiveLetter(returnType));
+ }
+
+ // push return
+ mv.visitLabel(l1);
+ if (! Void.TYPE.equals(returnType)) {
+ mv.visitInsn(getReturnInsn(returnType));
+ } else {
+ mv.visitInsn(POP);
+ mv.visitInsn(RETURN);
+ }
+
+ // catch InvocationTargetException
+ if (exceptionTypes.length > 0) {
+ mv.visitLabel(l2);
+ mv.visitVarInsn(ASTORE, length);
+ Label l5 = new Label();
+ mv.visitLabel(l5);
+
+ for (int i = 0; i < exceptionTypes.length; i++) {
+ Class<?> exceptionType = exceptionTypes[i];
+
+ mv.visitLdcInsn(Type.getType("L" + exceptionType.getCanonicalName().replaceAll("\\.", "/") + ";"));
+ mv.visitVarInsn(ALOAD, length);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/InvocationTargetException", "getCause", "()Ljava/lang/Throwable;");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
+ Label l6 = new Label();
+ mv.visitJumpInsn(IFEQ, l6);
+ Label l7 = new Label();
+ mv.visitLabel(l7);
+ mv.visitVarInsn(ALOAD, length);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/InvocationTargetException", "getCause", "()Ljava/lang/Throwable;");
+ mv.visitTypeInsn(CHECKCAST, exceptionType.getCanonicalName().replaceAll("\\.", "/"));
+ mv.visitInsn(ATHROW);
+ mv.visitLabel(l6);
+
+ if (i == (exceptionTypes.length - 1)) {
+ mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ALOAD, length);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V");
+ mv.visitInsn(ATHROW);
+ }
+ }
+ }
+
+ // wrap any other exceptions with an UndeclaredThrowableException
+ mv.visitLabel(l3);
+ mv.visitVarInsn(ASTORE, length);
+ Label l8 = new Label();
+ mv.visitLabel(l8);
+ mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ALOAD, length);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V");
+ mv.visitInsn(ATHROW);
+ Label l9 = new Label();
+ mv.visitLabel(l9);
+
+ // finish this method
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ /**
+ * 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(Class<?> type) {
+ if (type.isPrimitive()) {
+ if (Integer.TYPE.equals(type)) {
+ return IRETURN;
+ } else if (Boolean.TYPE.equals(type)) {
+ return IRETURN;
+ } else if (Character.TYPE.equals(type)) {
+ return IRETURN;
+ } else if (Byte.TYPE.equals(type)) {
+ return IRETURN;
+ } else if (Short.TYPE.equals(type)) {
+ return IRETURN;
+ } else if (Float.TYPE.equals(type)) {
+ return FRETURN;
+ } else if (Long.TYPE.equals(type)) {
+ return LRETURN;
+ } else if (Double.TYPE.equals(type)) {
+ return DRETURN;
+ }
+ }
+
+ return ARETURN;
+ }
+
+
+ /**
+ * Returns the appropriate bytecode instruction to load a value from a variable to the stack
+ * @param type Type to load
+ * @return Bytecode instruction to use
+ */
+ private int getVarInsn(Class<?> type) {
+ if (type.isPrimitive()) {
+ if (Integer.TYPE.equals(type)) {
+ return ILOAD;
+ } else if (Boolean.TYPE.equals(type)) {
+ return ILOAD;
+ } else if (Character.TYPE.equals(type)) {
+ return ILOAD;
+ } else if (Byte.TYPE.equals(type)) {
+ return ILOAD;
+ } else if (Short.TYPE.equals(type)) {
+ return ILOAD;
+ } else if (Float.TYPE.equals(type)) {
+ return FLOAD;
+ } else if (Long.TYPE.equals(type)) {
+ return LLOAD;
+ } else if (Double.TYPE.equals(type)) {
+ return DLOAD;
+ }
+ }
+
+ throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
+ }
+
+ /**
+ * Returns the name of the Java method to call to get the primitive value from an Object - e.g. intValue for java.lang.Integer
+ * @param type Type whose primitive method we want to lookup
+ * @return The name of the method to use
+ */
+ private String getPrimitiveMethod(Class<?> type) {
+ if (Integer.TYPE.equals(type)) {
+ return "intValue";
+ } else if (Boolean.TYPE.equals(type)) {
+ return "booleanValue";
+ } else if (Character.TYPE.equals(type)) {
+ return "charValue";
+ } else if (Byte.TYPE.equals(type)) {
+ return "byteValue";
+ } else if (Short.TYPE.equals(type)) {
+ return "shortValue";
+ } else if (Float.TYPE.equals(type)) {
+ return "floatValue";
+ } else if (Long.TYPE.equals(type)) {
+ return "longValue";
+ } else if (Double.TYPE.equals(type)) {
+ return "doubleValue";
+ }
+
+ throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
+ }
+
+ /**
+ * Gets the string to use for CHECKCAST instruction, returning the correct value for any type, including primitives and arrays
+ * @param returnType The type to cast to with CHECKCAST
+ * @return CHECKCAST parameter
+ */
+ String getCastType(Class<?> returnType) {
+ if (returnType.isPrimitive()) {
+ return getWrapperType(returnType);
+ } else {
+ return getAsmTypeAsString(returnType, false);
+ }
+ }
+
+ /**
+ * Returns the wrapper type for a primitive, e.g. java.lang.Integer for int
+ * @param type
+ * @return
+ */
+ private String getWrapperType(Class<?> type) {
+ if (Integer.TYPE.equals(type)) {
+ return Integer.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Boolean.TYPE.equals(type)) {
+ return Boolean.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Character.TYPE.equals(type)) {
+ return Character.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Byte.TYPE.equals(type)) {
+ return Byte.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Short.TYPE.equals(type)) {
+ return Short.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Float.TYPE.equals(type)) {
+ return Float.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Long.TYPE.equals(type)) {
+ return Long.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Double.TYPE.equals(type)) {
+ return Double.class.getCanonicalName().replaceAll("\\.", "/");
+ } else if (Void.TYPE.equals(type)) {
+ return Void.class.getCanonicalName().replaceAll("\\.", "/");
+ }
+
+ throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
+ }
+
+ /**
+ * Invokes the most appropriate bytecode instruction to put a number on the stack
+ * @param mv
+ * @param i
+ */
+ private void pushIntOntoStack(MethodVisitor mv, int i) {
+ if (i == 0) {
+ mv.visitInsn(ICONST_0);
+ } else if (i == 1) {
+ mv.visitInsn(ICONST_1);
+ } else if (i == 2) {
+ mv.visitInsn(ICONST_2);
+ } else if (i == 3) {
+ mv.visitInsn(ICONST_3);
+ } else if (i == 4) {
+ mv.visitInsn(ICONST_4);
+ } else if (i == 5) {
+ mv.visitInsn(ICONST_5);
+ } else if (i > 5 && i <= 255) {
+ mv.visitIntInsn(BIPUSH, i);
+ } else {
+ mv.visitIntInsn(SIPUSH, i);
+ }
+ }
+
+ /**
+ * pushes an array of the specified size to the method visitor. The generated bytecode will leave
+ * the new array at the top of the stack.
+ *
+ * @param mv MethodVisitor to use
+ * @param size Size of the array to create
+ * @param type Type of array to create
+ * @throws ProxyGenerationException
+ */
+ private void createArrayDefinition(MethodVisitor mv, int size, Class<?> type) throws ProxyGenerationException {
+ // create a new array of java.lang.class (2)
+
+ if (size < 0) {
+ throw new ProxyGenerationException("Array size cannot be less than zero");
+ }
+
+ pushIntOntoStack(mv, size);
+
+ mv.visitTypeInsn(ANEWARRAY, type.getCanonicalName().replaceAll("\\.", "/"));
+ }
+
+
+ String getMethodSignatureAsString(Class<?> returnType, Class<?>[] parameterTypes) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("(");
+ for (Class<?> parameterType : parameterTypes) {
+ builder.append(getAsmTypeAsString(parameterType, true));
+ }
+
+ builder.append(")");
+ builder.append(getAsmTypeAsString(returnType, true));
+
+ return builder.toString();
+ }
+
+ /**
+ * Returns the single letter that matches the given primitive in bytecode instructions
+ * @param type
+ * @return
+ */
+ private String getPrimitiveLetter(Class<?> type) {
+ if (Integer.TYPE.equals(type)) {
+ return "I";
+ } else if (Void.TYPE.equals(type)) {
+ return "V";
+ } else if (Boolean.TYPE.equals(type)) {
+ return "Z";
+ } else if (Character.TYPE.equals(type)) {
+ return "C";
+ } else if (Byte.TYPE.equals(type)) {
+ return "B";
+ } else if (Short.TYPE.equals(type)) {
+ return "S";
+ } else if (Float.TYPE.equals(type)) {
+ return "F";
+ } else if (Long.TYPE.equals(type)) {
+ return "J";
+ } else if (Double.TYPE.equals(type)) {
+ return "D";
+ }
+
+ throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
+ }
+
+ /**
+ * Converts a class to a String suitable for ASM.
+ * @param parameterType Class to convert
+ * @param wrap True if a non-array object should be wrapped with L and ; - e.g. Ljava/lang/Integer;
+ * @return String to use for ASM
+ */
+ public String getAsmTypeAsString(Class<?> parameterType, boolean wrap) {
+ if (parameterType.isArray()) {
+ if (parameterType.getComponentType().isPrimitive()) {
+ Class<?> componentType = parameterType.getComponentType();
+ return "[" + getPrimitiveLetter(componentType);
+ } else {
+ return "[" + getAsmTypeAsString(parameterType.getComponentType(), true);
+ }
+ } else {
+ if (! parameterType.isPrimitive()) {
+ if (wrap) {
+ return "L" + parameterType.getCanonicalName().replaceAll("\\.", "/") + ";";
+ } else {
+ return parameterType.getCanonicalName().replaceAll("\\.", "/");
+ }
+ } else {
+ return getPrimitiveLetter(parameterType);
+ }
+ }
+ }
+
+}
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/ProxyGenerationException.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/ProxyGenerationException.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/ProxyGenerationException.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/ProxyGenerationException.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,36 @@
+/**
+ * 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.openejb.util.proxy;
+
+public class ProxyGenerationException extends Exception {
+
+ public ProxyGenerationException() {
+ }
+
+ public ProxyGenerationException(String message) {
+ super(message);
+ }
+
+ public ProxyGenerationException(Throwable cause) {
+ super(cause);
+ }
+
+ public ProxyGenerationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImplTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImplTest.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImplTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImplTest.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,874 @@
+/**
+ * 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.openejb.util.proxy;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+public class LocalBeanProxyGeneratorImplTest extends TestCase {
+
+ public class Call {
+ private String methodName;
+ private Class<?>[] parameterTypes;
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public void setMethodName(String methodName) {
+ this.methodName = methodName;
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return parameterTypes;
+ }
+
+ public void setParameterTypes(Class<?>[] parameterTypes) {
+ this.parameterTypes = parameterTypes;
+ }
+
+ public Call() {
+ super();
+ }
+
+ public Call(String methodName, Class<?>[] parameterTypes) {
+ this.parameterTypes = parameterTypes;
+ this.methodName = methodName;
+ }
+ }
+
+ private class TestInvocationHandler implements InvocationHandler {
+
+ private final Object object;
+ private List<Call> calls = new ArrayList<Call>();
+
+ public TestInvocationHandler(Object object) {
+ super();
+ this.object = object;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ StringBuilder builder = new StringBuilder();
+ builder.append(method.getName());
+ builder.append("(");
+
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ for (int i = 0; i < parameterTypes.length; i++) {
+ Class<?> parameterType = parameterTypes[i];
+
+ if (i > 0) {
+ builder.append(",");
+ }
+
+ builder.append(getObjectType(parameterType));
+ }
+
+ builder.append(")");
+
+ System.out.println(builder.toString());
+
+ Method m = object.getClass().getMethod(method.getName(), method.getParameterTypes());
+ calls.add(new Call(m.getName(), m.getParameterTypes()));
+ return m.invoke(object, args);
+ }
+
+ private String getObjectType(Class<?> parameterType) {
+ String type = "";
+
+ if (parameterType.isPrimitive()) {
+ if (Boolean.TYPE.equals(parameterType)) {
+ type = "boolean";
+ }
+
+ if (Character.TYPE.equals(parameterType)) {
+ type = "character";
+ }
+
+ if (Byte.TYPE.equals(parameterType)) {
+ type = "byte";
+ }
+
+ if (Short.TYPE.equals(parameterType)) {
+ type = "short";
+ }
+
+ if (Integer.TYPE.equals(parameterType)) {
+ type = "int";
+ }
+
+ if (Long.TYPE.equals(parameterType)) {
+ type = "long";
+ }
+
+ if (Float.TYPE.equals(parameterType)) {
+ type = "float";
+ }
+
+ if (Double.TYPE.equals(parameterType)) {
+ type = "double";
+ }
+
+ if (Void.TYPE.equals(parameterType)) {
+ type = "void";
+ }
+
+ if (Boolean.TYPE.equals(parameterType)) {
+ type = "boolean";
+ }
+ } else {
+ type = parameterType.getCanonicalName();
+ }
+
+ if (parameterType.isArray()) {
+ type = type + "[]";
+ }
+
+ return type;
+ }
+
+ public Call[] getCalls() {
+ return calls.toArray(new Call[calls.size()]);
+ }
+ }
+
+ private class TestClassLoader extends ClassLoader {
+
+ public TestClassLoader() {
+ super();
+ }
+
+ public TestClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ public Class addClass(String name, byte[] cls) {
+ Class c = defineClass(name, cls, 0, cls.length);
+ return c;
+ }
+ }
+
+ private SampleLocalBean loadProxy() throws Exception {
+ SampleLocalBean bean = new SampleLocalBean();
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(bean);
+
+ return loadProxy(invocationHandler);
+ }
+
+ private SampleLocalBean loadProxy(TestInvocationHandler invocationHandler) throws Exception {
+ String name = "TestProxy";
+ byte[] cls = new LocalBeanProxyGeneratorImpl().generateProxy(SampleLocalBean.class, name);
+
+ FileOutputStream os = new FileOutputStream("C:\\Temp\\TestProxy.class");
+ os.write(cls);
+ os.close();
+
+ ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+ TestClassLoader newCl = new TestClassLoader(oldCl);
+ Thread.currentThread().setContextClassLoader(newCl);
+ newCl.addClass(name, cls);
+
+ Class<?> proxyClass = newCl.loadClass(name);
+
+ SampleLocalBean proxy = (SampleLocalBean) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(invocationHandler);
+ return proxy;
+ }
+
+ public void testShouldReturnCorrectMethodSignatures() throws Exception {
+ LocalBeanProxyGeneratorImpl proxyGenerator = new LocalBeanProxyGeneratorImpl();
+ assertEquals("(II)I", proxyGenerator.getMethodSignatureAsString(Integer.TYPE, new Class<?>[] { Integer.TYPE, Integer.TYPE }));
+ assertEquals("(ZZ)Z", proxyGenerator.getMethodSignatureAsString(Boolean.TYPE, new Class<?>[] { Boolean.TYPE, Boolean.TYPE }));
+ assertEquals("(CC)C", proxyGenerator.getMethodSignatureAsString(Character.TYPE, new Class<?>[] { Character.TYPE, Character.TYPE }));
+ assertEquals("(BB)B", proxyGenerator.getMethodSignatureAsString(Byte.TYPE, new Class<?>[] { Byte.TYPE, Byte.TYPE }));
+ assertEquals("(SS)S", proxyGenerator.getMethodSignatureAsString(Short.TYPE, new Class<?>[] { Short.TYPE, Short.TYPE }));
+ assertEquals("(JJ)J", proxyGenerator.getMethodSignatureAsString(Long.TYPE, new Class<?>[] { Long.TYPE, Long.TYPE }));
+ assertEquals("(FF)F", proxyGenerator.getMethodSignatureAsString(Float.TYPE, new Class<?>[] { Float.TYPE, Float.TYPE }));
+ assertEquals("(DD)D", proxyGenerator.getMethodSignatureAsString(Double.TYPE, new Class<?>[] { Double.TYPE, Double.TYPE }));
+ assertEquals("()V", proxyGenerator.getMethodSignatureAsString(Void.TYPE, new Class<?>[] { }));
+
+ assertEquals("([I[I)[I", proxyGenerator.getMethodSignatureAsString(int[].class, new Class<?>[] { int[].class, int[].class }));
+ assertEquals("([Z[Z)[Z", proxyGenerator.getMethodSignatureAsString(boolean[].class, new Class<?>[] { boolean[].class, boolean[].class }));
+ assertEquals("([C[C)[C", proxyGenerator.getMethodSignatureAsString(char[].class, new Class<?>[] { char[].class, char[].class }));
+ assertEquals("([B[B)[B", proxyGenerator.getMethodSignatureAsString(byte[].class, new Class<?>[] { byte[].class, byte[].class }));
+ assertEquals("([S[S)[S", proxyGenerator.getMethodSignatureAsString(short[].class, new Class<?>[] { short[].class, short[].class }));
+ assertEquals("([J[J)[J", proxyGenerator.getMethodSignatureAsString(long[].class, new Class<?>[] { long[].class, long[].class }));
+ assertEquals("([F[F)[F", proxyGenerator.getMethodSignatureAsString(float[].class, new Class<?>[] { float[].class, float[].class }));
+ assertEquals("([D[D)[D", proxyGenerator.getMethodSignatureAsString(double[].class, new Class<?>[] { double[].class, double[].class }));
+
+ assertEquals("(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", proxyGenerator.getMethodSignatureAsString(Integer.class, new Class<?>[] { Integer.class, Integer.class }));
+ assertEquals("([Ljava/lang/Integer;[Ljava/lang/Integer;)[Ljava/lang/Integer;", proxyGenerator.getMethodSignatureAsString(Integer[].class, new Class<?>[] { Integer[].class, Integer[].class }));
+ }
+
+ @Test
+ public void testDoWork() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ proxy.doWork();
+
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("doWork", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testEcho() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ String result = proxy.echo("Some text");
+
+ assertEquals("Some text", result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("echo", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { String.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddIntInt() throws Exception {
+ int value1 = 32;
+ int value2 = 64;
+ int expectedResult = 96;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ int result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Integer.TYPE, Integer.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddIntegerInteger() throws Exception {
+ Integer value1 = 32;
+ Integer value2 = 64;
+ Integer expectedResult = 96;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Integer result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Integer.class, Integer.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testIsTrueBoolean() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ boolean result = proxy.isTrue(new Boolean(true).booleanValue());
+
+ assertTrue(result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("isTrue", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Boolean.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testIsTrueBoolean1() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Boolean result = proxy.isTrue(new Boolean(true));
+
+ assertTrue(result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("isTrue", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Boolean.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testNextCharChar() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ char result = proxy.nextChar(new Character('A').charValue());
+
+ assertEquals('B', result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("nextChar", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Character.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testNextCharCharacter() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Character result = proxy.nextChar(new Character('A'));
+
+ assertEquals(new Character('B'), result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("nextChar", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Character.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddShortShort() throws Exception {
+ short value1 = 32;
+ short value2 = 64;
+ short expectedResult = 96;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ short result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Short.TYPE, Short.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddShortShort1() throws Exception {
+ Short value1 = 32;
+ Short value2 = 64;
+ Short expectedResult = 96;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Short result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Short.class, Short.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddLongLong() throws Exception {
+ long value1 = 32;
+ long value2 = 64;
+ long expectedResult = 96;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ long result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Long.TYPE, Long.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddLongLong1() throws Exception {
+ Long value1 = 32L;
+ Long value2 = 64L;
+ Long expectedResult = 96L;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Long result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Long.class, Long.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddDoubleDouble() throws Exception {
+ double value1 = 32;
+ double value2 = 64;
+ double expectedResult = 96;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ double result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Double.TYPE, Double.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddDoubleDouble1() throws Exception {
+ Double value1 = 32d;
+ Double value2 = 64d;
+ Double expectedResult = 96d;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Double result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Double.class, Double.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddFloatFloat() throws Exception {
+ float value1 = 32f;
+ float value2 = 64f;
+ float expectedResult = 96f;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ float result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Float.TYPE, Float.TYPE }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAddFloatFloat1() throws Exception {
+ Float value1 = 32f;
+ Float value2 = 64f;
+ Float expectedResult = 96f;
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Float result = proxy.add(value1, value2);
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("add", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Float.class, Float.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testCreateSomeObjects() throws Exception {
+ ProxyTestObject[] expectedResult = new ProxyTestObject[] { new ProxyTestObject("object1"), new ProxyTestObject("object2") };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ ProxyTestObject[] result = proxy.createSomeObjects();
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("createSomeObjects", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReturnFirst() throws Exception {
+ ProxyTestObject expectedResult = new ProxyTestObject("object1");
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ ProxyTestObject result = proxy.returnFirst(new ProxyTestObject[] { new ProxyTestObject("object1"), new ProxyTestObject("object2") });
+
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("returnFirst", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { ProxyTestObject[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseIntArray() throws Exception {
+ int value1 = 2;
+ int value2 = 4;
+ int value3 = 6;
+ int value4 = 8;
+ int value5 = 10;
+
+ int[] value = new int[] { value1, value2, value3, value4, value5 };
+ int[] expectedResult = new int[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ int[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { int[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseIntegerArray() throws Exception {
+ Integer value1 = 2;
+ Integer value2 = 4;
+ Integer value3 = 6;
+ Integer value4 = 8;
+ Integer value5 = 10;
+
+ Integer[] value = new Integer[] { value1, value2, value3, value4, value5 };
+ Integer[] expectedResult = new Integer[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Integer[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Integer[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseBooleanArray() throws Exception {
+ boolean value1 = true;
+ boolean value2 = false;
+
+ boolean[] value = new boolean[] { value1, value2 };
+ boolean[] expectedResult = new boolean[] { value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ boolean[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { boolean[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseBooleanArray1() throws Exception {
+ Boolean value1 = true;
+ Boolean value2 = false;
+
+ Boolean[] value = new Boolean[] { value1, value2 };
+ Boolean[] expectedResult = new Boolean[] { value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Boolean[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Boolean[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseCharArray() throws Exception {
+ char value1 = 'j';
+ char value2 = 'o';
+ char value3 = 'n';
+
+ char[] value = new char[] { value1, value2, value3 };
+ char[] expectedResult = new char[] { value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ char[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { char[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseCharacterArray() throws Exception {
+ Character value1 = 'j';
+ Character value2 = 'o';
+ Character value3 = 'n';
+
+ Character[] value = new Character[] { value1, value2, value3 };
+ Character[] expectedResult = new Character[] { value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Character[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Character[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseShortArray() throws Exception {
+ short value1 = 2;
+ short value2 = 4;
+ short value3 = 6;
+ short value4 = 8;
+ short value5 = 10;
+
+ short[] value = new short[] { value1, value2, value3, value4, value5 };
+ short[] expectedResult = new short[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ short[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { short[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseShortArray1() throws Exception {
+ Short value1 = 2;
+ Short value2 = 4;
+ Short value3 = 6;
+ Short value4 = 8;
+ Short value5 = 10;
+
+ Short[] value = new Short[] { value1, value2, value3, value4, value5 };
+ Short[] expectedResult = new Short[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Short[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Short[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseLongArray() throws Exception {
+ long value1 = 2L;
+ long value2 = 4L;
+ long value3 = 6L;
+ long value4 = 8L;
+ long value5 = 10L;
+
+ long[] value = new long[] { value1, value2, value3, value4, value5 };
+ long[] expectedResult = new long[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ long[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { long[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseLongArray1() throws Exception {
+ Long value1 = 2L;
+ Long value2 = 4L;
+ Long value3 = 6L;
+ Long value4 = 8L;
+ Long value5 = 10L;
+
+ Long[] value = new Long[] { value1, value2, value3, value4, value5 };
+ Long[] expectedResult = new Long[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Long[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Long[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseDoubleArray() throws Exception {
+ double value1 = 2d;
+ double value2 = 4d;
+ double value3 = 6d;
+ double value4 = 8d;
+ double value5 = 10d;
+
+ double[] value = new double[] { value1, value2, value3, value4, value5 };
+ double[] expectedResult = new double[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ double[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { double[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseDoubleArray1() throws Exception {
+ Double value1 = 2d;
+ Double value2 = 4d;
+ Double value3 = 6d;
+ Double value4 = 8d;
+ Double value5 = 10d;
+
+ Double[] value = new Double[] { value1, value2, value3, value4, value5 };
+ Double[] expectedResult = new Double[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Double[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Double[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseFloatArray() throws Exception {
+ float value1 = 2f;
+ float value2 = 4f;
+ float value3 = 6f;
+ float value4 = 8f;
+ float value5 = 10f;
+
+ float[] value = new float[] { value1, value2, value3, value4, value5 };
+ float[] expectedResult = new float[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ float[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { float[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testReverseFloatArray1() throws Exception {
+ Float value1 = 2f;
+ Float value2 = 4f;
+ Float value3 = 6f;
+ Float value4 = 8f;
+ Float value5 = 10f;
+
+ Float[] value = new Float[] { value1, value2, value3, value4, value5 };
+ Float[] expectedResult = new Float[] { value5, value4, value3, value2, value1 };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ Float[] result = proxy.reverse(value);
+
+ assertTrue(Arrays.equals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverse", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { Float[].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testThrowAnException() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+
+ try {
+ proxy.throwAnException();
+ } catch (ProxyTestException e) {
+ }
+
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("throwAnException", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testThrowAnotherException() throws Exception {
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+
+ try {
+ proxy.throwAnotherException();
+ } catch (IOException e) {
+ }
+
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("throwAnotherException", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testGenericCollections() throws Exception {
+ List<ProxyTestObject> value = new ArrayList<ProxyTestObject>();
+ value.add(new ProxyTestObject("test1"));
+ value.add(new ProxyTestObject("test2"));
+
+ List<ProxyTestObject> expectedResult = new ArrayList<ProxyTestObject>();
+ expectedResult.add(new ProxyTestObject("test2"));
+ expectedResult.add(new ProxyTestObject("test1"));
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ List<ProxyTestObject> result = proxy.reverseList(value);
+
+ assertEquals(expectedResult, result);
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverseList", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { List.class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testMultiDimensionArrays() throws Exception {
+ int[][] value = new int[][] { new int[] { 1, 2, 3, 4 }, new int[] { 5, 6, 7, 8 } };
+ int[][] expectedResult = new int[][] { new int[] { 8, 7, 6, 5 }, new int[] { 4, 3, 2, 1 } };
+
+ TestInvocationHandler invocationHandler = new TestInvocationHandler(new SampleLocalBean());
+ SampleLocalBean proxy = loadProxy(invocationHandler);
+ int[][] result = proxy.reverseAll(value);
+
+ assertTrue(Arrays.deepEquals(expectedResult, result));
+ assertEquals(1, invocationHandler.getCalls().length);
+ Call call = invocationHandler.getCalls()[0];
+ assertEquals("reverseAll", call.getMethodName());
+ assertTrue(Arrays.equals(new Class<?>[] { int[][].class }, call.getParameterTypes()));
+ }
+
+ @Test
+ public void testAreThoseTwoMethodsTheSame() throws Exception {
+ LocalBeanProxyGeneratorImpl proxyGenerator = new LocalBeanProxyGeneratorImpl();
+
+ assertEquals("[I", proxyGenerator.getAsmTypeAsString(int[].class, true));
+ assertEquals("[[I", proxyGenerator.getAsmTypeAsString(int[][].class, false));
+ assertEquals("Lorg/apache/openejb/util/proxy/ProxyTestObject;", proxyGenerator.getAsmTypeAsString(ProxyTestObject.class, true));
+ assertEquals("org/apache/openejb/util/proxy/ProxyTestObject", proxyGenerator.getAsmTypeAsString(ProxyTestObject.class, false));
+ assertEquals("[Lorg/apache/openejb/util/proxy/ProxyTestObject;", proxyGenerator.getAsmTypeAsString(ProxyTestObject[].class, true));
+ assertEquals("[Lorg/apache/openejb/util/proxy/ProxyTestObject;", proxyGenerator.getAsmTypeAsString(ProxyTestObject[].class, false));
+
+ assertEquals("java/lang/Integer", proxyGenerator.getCastType(Integer.TYPE));
+ assertEquals("java/lang/Integer", proxyGenerator.getCastType(Integer.class));
+ assertEquals("org/apache/openejb/util/proxy/ProxyTestObject", proxyGenerator.getCastType(ProxyTestObject.class));
+ }
+}
Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestException.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestException.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestException.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestException.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,37 @@
+/**
+ * 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.openejb.util.proxy;
+
+public class ProxyTestException extends Exception {
+
+ public ProxyTestException() {
+ super();
+ }
+
+ public ProxyTestException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+
+ public ProxyTestException(String message) {
+ super(message);
+ }
+
+ public ProxyTestException(Throwable throwable) {
+ super(throwable);
+ }
+
+}
Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestObject.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestObject.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestObject.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/ProxyTestObject.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,60 @@
+/**
+ * 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.openejb.util.proxy;
+
+public class ProxyTestObject {
+ private String info;
+
+ public ProxyTestObject() {
+ super();
+ }
+
+ public ProxyTestObject(String info) {
+ this.info = info;
+ }
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((info == null) ? 0 : info.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ProxyTestObject other = (ProxyTestObject) obj;
+ if (info == null) {
+ if (other.info != null)
+ return false;
+ } else if (!info.equals(other.info))
+ return false;
+ return true;
+ }
+}
Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/SampleLocalBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/SampleLocalBean.java?rev=909833&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/SampleLocalBean.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/proxy/SampleLocalBean.java Sat Feb 13 14:50:44 2010
@@ -0,0 +1,360 @@
+/**
+ * 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.openejb.util.proxy;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ejb.LocalBean;
+
+
+@LocalBean
+public class SampleLocalBean {
+
+ public SampleLocalBean() {
+ super();
+ }
+
+ /* 1. void return, no arg */
+ public void doWork() {
+ System.out.println("void doWork()");
+ }
+
+ /* 2. simple object */
+ public String echo(String input) {
+ return input;
+ }
+
+ /* 3a int primitive */
+ public int add(int no1, int no2) {
+ return no1 + no2;
+ }
+
+ /* 3b int object */
+ public Integer add(Integer no1, Integer no2) {
+ return no1 + no2;
+ }
+
+ /* 3c bool primitive */
+ public boolean isTrue (boolean value) {
+ return value;
+ }
+
+ /* 3d bool object */
+ public Boolean isTrue (Boolean value) {
+ return value;
+ }
+
+ /* 3e char primitive */
+ public char nextChar (char value) {
+ if (value > 'z') return 'A';
+ char next = value;
+ next++;
+ return next;
+ }
+
+ /* 3f char object */
+ public Character nextChar (Character value) {
+ if (value > 'z') return 'A';
+ char next = value;
+ next++;
+ return next;
+ }
+
+ /* 3g short primitive */
+ public short add(short no1, short no2) {
+ return (short) (no1 + no2);
+ }
+
+ /* 3h short object */
+ public Short add(Short no1, Short no2) {
+ return new Short((short) (no1 + no2));
+ }
+
+ /* 3i long primitive */
+ public long add(long no1, long no2) {
+ return (long) (no1 + no2);
+ }
+
+ /* 3j long object */
+ public Long add(Long no1, Long no2) {
+ return (long) (no1 + no2);
+ }
+
+ /* 3k double primitive */
+ public double add(double no1, double no2) {
+ return (double) (no1 + no2);
+ }
+
+ /* 3l double object */
+ public Double add(Double no1, Double no2) {
+ return (Double) (no1 + no2);
+ }
+
+ /* 3m float primitive */
+ public float add(float no1, float no2) {
+ return (float) (no1 + no2);
+ }
+
+ /* 3n float object*/
+ public Float add(Float no1, Float no2) {
+ return (Float) (no1 + no2);
+ }
+
+ /* 4a simple object array */
+ public ProxyTestObject[] createSomeObjects() {
+ ProxyTestObject object1 = new ProxyTestObject("object1");
+ ProxyTestObject object2 = new ProxyTestObject("object2");
+
+ return new ProxyTestObject[] { object1, object2 };
+ }
+
+ /* 4b simple object array */
+ public ProxyTestObject returnFirst(ProxyTestObject[] objects) {
+ if (objects == null || objects.length == 0) {
+ return null;
+ }
+
+ return objects[0];
+ }
+
+ /* 5a int primitive */
+ public int[] reverse(int[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ int[] result = new int[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5b int object */
+ public Integer[] reverse(Integer[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Integer[] result = new Integer[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5c bool primitive */
+ public boolean[] reverse (boolean[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ boolean[] result = new boolean[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5d bool object */
+ public Boolean[] reverse (Boolean[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Boolean[] result = new Boolean[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5e char primitive */
+ public char[] reverse (char[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ char[] result = new char[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5f char object */
+ public Character[] reverse (Character[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Character[] result = new Character[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5g short primitive */
+ public short[] reverse(short[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ short[] result = new short[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5h short object */
+ public Short[] reverse(Short[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Short[] result = new Short[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5i long primitive */
+ public long[] reverse(long[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ long[] result = new long[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5j long object */
+ public Long[] reverse(Long[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Long[] result = new Long[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5k double primitive */
+ public double[] reverse(double[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ double[] result = new double[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5l double object */
+ public Double[] reverse(Double[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Double[] result = new Double[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5m float primitive */
+ public float[] reverse(float[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ float[] result = new float[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 5n float object*/
+ public Float[] reverse(Float[] value) {
+ if (value == null || value.length == 0) {
+ return value;
+ }
+
+ Float[] result = new Float[value.length];
+ for (int i = 0; i < value.length; i++) {
+ result[(value.length - 1) - i] = value[i];
+ }
+
+ return result;
+ }
+
+ /* 6 throw and exception */
+ public String throwAnException() throws ProxyTestException {
+ throw new ProxyTestException();
+ }
+
+ public String throwAnotherException() throws ProxyTestException, IOException {
+ throw new IOException();
+ }
+
+ /* 7 test generics */
+ public List<ProxyTestObject> reverseList(List<ProxyTestObject> objectList) {
+ List<ProxyTestObject> result = new ArrayList<ProxyTestObject>();
+ for (int i = objectList.size() - 1; i >= 0; i--) {
+ result.add(objectList.get(i));
+ }
+
+ return result;
+ }
+
+ /* 8 test multi dimension array */
+ public int[][] reverseAll(int[][] value) {
+ int[][] result = new int[value.length][];
+ for (int i = 0; i < value.length; i++) {
+ result[i] = reverse(value[(value.length - 1) - i]);
+ }
+
+ return result;
+ }
+}