1 package net.sf.cglib;
2
3 import net.sf.cglib.core.*;
4 import java.lang.reflect.Method;
5 import java.util.*;
6 import org.objectweb.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("net.sf.cglib.InvocationHandler");
15 private static final Type UNDECLARED_THROWABLE_EXCEPTION =
16 TypeUtils.parseType("net.sf.cglib.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);
34
35 CodeEmitter e = ce.begin_method(context.getModifiers(method),
36 ReflectUtils.getSignature(method),
37 ReflectUtils.getExceptionTypes(method));
38 Block handler = e.begin_block();
39 context.emitCallback(e);
40 e.load_this();
41 e.getfield(fieldName);
42 e.create_arg_array();
43 e.invoke_interface(INVOCATION_HANDLER, INVOKE);
44 e.unbox(Type.getType(method.getReturnType()));
45 e.return_value();
46 handler.end();
47
48 /* generates:
49 } catch (RuntimeException e) {
50 throw e;
51 } catch (Error e) {
52 throw e;
53 } catch (<DeclaredException> e) {
54 throw e;
55 } catch (Throwable e) {
56 throw new UndeclaredThrowableException(e);
57 }
58 */
59 Class[] exceptionTypes = method.getExceptionTypes();
60 Set exceptionSet = new HashSet(Arrays.asList(exceptionTypes));
61 if (!(exceptionSet.contains(Exception.class) ||
62 exceptionSet.contains(Throwable.class))) {
63 if (!exceptionSet.contains(RuntimeException.class)) {
64 e.catch_exception(handler, Constants.TYPE_RUNTIME_EXCEPTION);
65 e.athrow();
66 }
67 if (!exceptionSet.contains(Error.class)) {
68 e.catch_exception(handler, Constants.TYPE_ERROR);
69 e.athrow();
70 }
71 for (int i = 0; i < exceptionTypes.length; i++) {
72 e.catch_exception(handler, Type.getType(exceptionTypes[i]));
73 e.athrow();
74 }
75 // e -> eo -> oeo -> ooe -> o
76 e.catch_exception(handler, Constants.TYPE_THROWABLE);
77 e.new_instance(UNDECLARED_THROWABLE_EXCEPTION);
78 e.dup_x1();
79 e.swap();
80 e.invoke_constructor(UNDECLARED_THROWABLE_EXCEPTION, CSTRUCT_THROWABLE);
81 e.athrow();
82 }
83 e.end_method();
84 }
85 }
86
87 public void generateStatic(CodeEmitter e, final Context context) {
88 for (Iterator it = context.getMethods(); it.hasNext();) {
89 Method method = (Method)it.next();
90 ComplexOps.load_method(e, method);
91 e.putfield(getFieldName(context, method));
92 }
93 }
94 }
This page was automatically generated by Maven