1 3 package test.jmock.core.testsupport; 4 5 import java.lang.reflect.Method ; 6 import org.objectweb.asm.ClassWriter; 7 import org.objectweb.asm.Constants; 8 import org.objectweb.asm.Type; 9 10 11 public class MethodFactory extends ClassLoader 12 { 13 public static Class [] NO_ARGUMENTS = {}; 14 public static Class [] NO_EXCEPTIONS = {}; 15 16 17 public Method newMethodReturning( Class returnType ) { 18 return newMethod("ignoredMethodName", NO_ARGUMENTS, returnType, NO_EXCEPTIONS); 19 } 20 21 public Method newMethod( final String methodName, 22 final Class [] argTypes, 23 final Class returnType, 24 final Class [] exceptionTypes ) 25 { 26 ClassLoader classLoader = new ClassLoader () 27 { 28 protected Class findClass( String interfaceName ) { 29 ClassWriter writer = new ClassWriter(true); 30 31 writer.visit(Constants.ACC_PUBLIC | Constants.ACC_INTERFACE, 32 nameToClassFormat(interfaceName), 33 "java/lang/Object", 34 null, 35 null ); 36 37 writer.visitMethod(Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT, 38 methodName, 39 methodDescriptor(returnType, argTypes), 40 classNamesInClassFormat(exceptionTypes), 41 null ); 42 43 byte[] classAsBytes = writer.toByteArray(); 44 45 return defineClass(interfaceName, classAsBytes, 0, classAsBytes.length); 46 } 47 }; 48 49 try { 50 Class interfaceClass = classLoader.loadClass("InterfaceDefining_" + methodName); 51 return interfaceClass.getMethod(methodName, argTypes); 52 } 53 catch (ClassNotFoundException ex) { 54 throw new Error (ex); 55 } 56 catch (NoSuchMethodException ex) { 57 throw new Error (ex); 58 } 59 } 60 61 static String nameToClassFormat( String name ) { 62 return name.replace('.', '/'); 63 } 64 65 static String [] classNamesInClassFormat( Class [] classes ) { 66 String [] namesInClassFormat = new String [classes.length]; 67 68 for (int i = 0; i < classes.length; i++) { 69 namesInClassFormat[i] = nameToClassFormat(classes[i].getName()); 70 } 71 72 return namesInClassFormat; 73 } 74 75 static String methodDescriptor( Class returnClass, Class [] argClasses ) { 76 return Type.getMethodDescriptor(Type.getType(returnClass), classesToTypes(argClasses)); 77 } 78 79 private static Type[] classesToTypes( Class [] classes ) { 80 Type[] types = new Type[classes.length]; 81 82 for (int i = 0; i < classes.length; i++) { 83 types[i] = Type.getType(classes[i]); 84 } 85 86 return types; 87 } 88 } 89 | Popular Tags |