/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.test.proxycompiler.test; import java.lang.reflect.Method; import junit.framework.*; import org.jboss.logging.Logger; import org.jboss.proxy.compiler.*; /** * Test the ability of the proxy compiler to create proxies for * simple/complex interfaces and classes. * * @version <tt>$Revision: 81036 $</tt> * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> */ public class ProxyCompilerUnitTestCase extends TestCase { private static final Logger log = Logger.getLogger(ProxyCompilerUnitTestCase.class); protected InvocationHandler handler; public ProxyCompilerUnitTestCase(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); handler = new LoggingInvocationHandler(log); } /** * Create a value for the given type. If non-void primitive, then * return a wrapper, else return null. */ protected static Object createValue(Class type) { Object rv = null; if (type.isPrimitive()) { if (type == Boolean.TYPE) rv = new Boolean(false); else if (type == Byte.TYPE) rv = new Byte((byte)0); else if (type == Character.TYPE) rv = new Character((char)0); else if (type == Short.TYPE) rv = new Short((short)0); else if (type == Integer.TYPE) rv = new Integer(0); else if (type == Long.TYPE) rv = new Long(0); else if (type == Float.TYPE) rv = new Float(0); else if (type == Double.TYPE) rv = new Double(0); else if (type == Void.TYPE) rv = null; else throw new Error("unreachable"); } return rv; } /** * An InvocationHandler which simplly logs all calls */ public static class LoggingInvocationHandler implements InvocationHandler { private Logger log; public LoggingInvocationHandler(final Logger log) { this.log = log; } public Object invoke(Object dummy, Method method, Object[] args) throws Throwable { log.debug("invoked: " + dummy + "," + method + "," + args); log.debug("arguments: "); for (int i=0; i<args.length; i++) { String msg = " arg" + i + ": " + args[i]; if (args[i] != null) msg += ", type=" + args[i].getClass(); log.debug(msg); } Object value = createValue(method.getReturnType()); log.debug("return value: " + value); return value; } } protected Object createProxy(Class type) throws Exception { Object proxy = Proxy.newProxyInstance(type.getClass().getClassLoader(), new Class[] { type }, handler); log.debug("new proxy: " + proxy); return proxy; } protected void invokeDeclaredMethods(Object obj, Class type) throws Exception { Method[] methods = type.getDeclaredMethods(); for (int i=0; i<methods.length; i++) { log.debug("Invoking method: " + methods[i]); Class[] pTypes = methods[i].getParameterTypes(); Object[] args = new Object[pTypes.length]; // create some dummy arg values for (int j=0; j<args.length; j++) { args[j] = createValue(pTypes[j]); } Object rv = methods[i].invoke(obj, args); log.debug("Method returned: " + rv); } } public static interface EmptyInterface { // empty } public void testEmptyInterface() throws Exception { createProxy(EmptyInterface.class); } public static interface SimpleInterface { void simple(); } public void testSimpleInterface() throws Exception { Object obj = createProxy(SimpleInterface.class); invokeDeclaredMethods(obj, SimpleInterface.class); } public static interface ReturnValues { // returns, no args void noargs(); Object Object_noargs(); byte byte__noargs(); boolean boolean_noargs(); char char_noargs(); int int_noargs(); short short_noargs(); long long_noargs(); float float_noargs(); double double_noargs(); } public void testReturnValues() throws Exception { Object obj = createProxy(ReturnValues.class); invokeDeclaredMethods(obj, ReturnValues.class); } public static interface CommonMethodParameters { // no returns, different args void boolean1(boolean a); void boolean2(boolean a, boolean b); void boolean3(boolean a, boolean b, boolean c); void boolean4(boolean a, boolean b, boolean c, boolean d); void byte1(byte a); void byte2(byte a, byte b); void byte3(byte a, byte b, byte c); void byte4(byte a, byte b, byte c, byte d); void char1(char a); void char2(char a, char b); void char3(char a, char b, char c); void char4(char a, char b, char c, char d); void short1(short a); void short2(short a, short b); void short3(short a, short b, short c); void short4(short a, short b, short c, short d); void int1(int a); void int2(int a, int b); void int3(int a, int b, int c); void int4(int a, int b, int c, int d); void long1(long a); void long2(long a, long b); void long3(long a, long b, long c); void long4(long a, long b, long c, long d); void long5(long a, long b, long c, long d, long e); void long6(long a, long b, long c, long d, long e, long f); void float1(float a); void float2(float a, float b); void float3(float a, float b, float c); void float4(float a, float b, float c, float d); void double1(double a); void double2(double a, double b); void double3(double a, double b, double c); void double4(double a, double b, double c, double d); void double5(double a, double b, double c, double d, double e); void double6(double a, double b, double c, double d, double e, double f); void Object1(Object a); void Object2(Object a, Object b); void Object3(Object a, Object b, Object c); void Object4(Object a, Object b, Object c, Object d); } public void testCommonMethodParameters() throws Exception { Object obj = createProxy(CommonMethodParameters.class); invokeDeclaredMethods(obj, CommonMethodParameters.class); } public static abstract class SimpleAbstractClass { public abstract void test1(); public abstract Object test2(); public abstract Object test3(Object obj); public abstract Object test4(Object obj) throws Exception; } public void testSimpleAbstractClass() throws Exception { Object obj = createProxy(SimpleAbstractClass.class); invokeDeclaredMethods(obj, SimpleAbstractClass.class); } public static interface ComplexInterface extends EmptyInterface, SimpleInterface, CommonMethodParameters { interface NestedInterface extends CommonMethodParameters { // blah } abstract class NestedAbstractClass extends SimpleAbstractClass { // blah } class ConcreteClass { // blah } long complex1(boolean a, byte b, char c, short d, int e, long f, float g, double h, Object i) throws Exception, Error, Throwable; Object[] complex2(boolean[] a, byte[] b, char[] c, short[] d, int[] e, long[] f, float[] g, double[] h, Object[] i) throws Exception, Error, Throwable; Object[][] complex3(boolean[][] a, byte[][] b, char[][] c, short[][] d, int[][] e, long[][] f, float[][] g, double[][] h, Object[][] i) throws Exception, Error, Throwable; Object[][][] complex4(boolean[] a, byte[][] b, char[][][] c, short[][][][] d, int[][][][][] e, long[][][][][][] f, float[][][][][][][] g, double[][][][][][][][] h, Object[][][][][][][][][] i) throws Exception, Error, Throwable; } public void testComplexInterface() throws Exception { Object obj = createProxy(ComplexInterface.class); invokeDeclaredMethods(obj, EmptyInterface.class); invokeDeclaredMethods(obj, SimpleInterface.class); invokeDeclaredMethods(obj, CommonMethodParameters.class); invokeDeclaredMethods(obj, ComplexInterface.class); } }