1 package org.logicalcobwebs.cglib.proxy; 2 3 import org.logicalcobwebs.cglib.core.*; 4 import java.lang.reflect.Method ; 5 import java.util.*; 6 import org.logicalcobwebs.asm.Type; 7 8 class InvocationHandlerGenerator 9 implements CallbackGenerator 10 { 11 public static final InvocationHandlerGenerator INSTANCE = new InvocationHandlerGenerator(); 12 13 private static final Type INVOCATION_HANDLER = 14 TypeUtils.parseType("org.logicalcobwebs.cglib.proxy.InvocationHandler"); 15 private static final Type UNDECLARED_THROWABLE_EXCEPTION = 16 TypeUtils.parseType("org.logicalcobwebs.cglib.proxy.UndeclaredThrowableException"); 17 private static final Type METHOD = 18 TypeUtils.parseType("java.lang.reflect.Method"); 19 private static final Signature INVOKE = 20 TypeUtils.parseSignature("Object invoke(Object, java.lang.reflect.Method, Object[])"); 21 private static final Signature CSTRUCT_THROWABLE = 22 TypeUtils.parseConstructor("Throwable"); 23 24 private String getFieldName(Context context, Method method) { 25 return "CGLIB$$METHOD_" + context.getUniqueName(method); 26 } 27 28 public void generate(ClassEmitter ce, final Context context) { 29 for (Iterator it = context.getMethods(); it.hasNext();) { 30 Method method = (Method )it.next(); 31 32 String fieldName = getFieldName(context, method); 33 ce.declare_field(Constants.PRIVATE_FINAL_STATIC, fieldName, METHOD, null, null); 34 35 CodeEmitter e = ce.begin_method(context.getModifiers(method), 36 ReflectUtils.getSignature(method), 37 ReflectUtils.getExceptionTypes(method), 38 null); 39 Block handler = e.begin_block(); 40 context.emitCallback(e, context.getIndex(method)); 41 e.load_this(); 42 e.getfield(fieldName); 43 e.create_arg_array(); 44 e.invoke_interface(INVOCATION_HANDLER, INVOKE); 45 e.unbox(Type.getType(method.getReturnType())); 46 e.return_value(); 47 handler.end(); 48 49 60 Class [] exceptionTypes = method.getExceptionTypes(); 61 Set exceptionSet = new HashSet(Arrays.asList(exceptionTypes)); 62 if (!(exceptionSet.contains(Exception .class) || 63 exceptionSet.contains(Throwable .class))) { 64 if (!exceptionSet.contains(RuntimeException .class)) { 65 e.catch_exception(handler, Constants.TYPE_RUNTIME_EXCEPTION); 66 e.athrow(); 67 } 68 if (!exceptionSet.contains(Error .class)) { 69 e.catch_exception(handler, Constants.TYPE_ERROR); 70 e.athrow(); 71 } 72 for (int i = 0; i < exceptionTypes.length; i++) { 73 e.catch_exception(handler, Type.getType(exceptionTypes[i])); 74 e.athrow(); 75 } 76 e.catch_exception(handler, Constants.TYPE_THROWABLE); 78 e.new_instance(UNDECLARED_THROWABLE_EXCEPTION); 79 e.dup_x1(); 80 e.swap(); 81 e.invoke_constructor(UNDECLARED_THROWABLE_EXCEPTION, CSTRUCT_THROWABLE); 82 e.athrow(); 83 } 84 e.end_method(); 85 } 86 } 87 88 public void generateStatic(CodeEmitter e, final Context context) { 89 for (Iterator it = context.getMethods(); it.hasNext();) { 90 Method method = (Method )it.next(); 91 EmitUtils.load_method(e, method); 92 e.putfield(getFieldName(context, method)); 93 } 94 } 95 } 96 | Popular Tags |