KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > cglib > proxy > InvocationHandlerGenerator


1 package org.logicalcobwebs.cglib.proxy;
2
3 import org.logicalcobwebs.cglib.core.*;
4 import java.lang.reflect.Method JavaDoc;
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 JavaDoc getFieldName(Context context, Method JavaDoc 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 JavaDoc method = (Method JavaDoc)it.next();
31
32             String JavaDoc 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             /* generates:
50                } catch (RuntimeException e) {
51                throw e;
52                } catch (Error e) {
53                throw e;
54                } catch (<DeclaredException> e) {
55                throw e;
56                } catch (Throwable e) {
57                throw new UndeclaredThrowableException(e);
58                }
59             */

60             Class JavaDoc[] exceptionTypes = method.getExceptionTypes();
61             Set exceptionSet = new HashSet(Arrays.asList(exceptionTypes));
62             if (!(exceptionSet.contains(Exception JavaDoc.class) ||
63                   exceptionSet.contains(Throwable JavaDoc.class))) {
64                 if (!exceptionSet.contains(RuntimeException JavaDoc.class)) {
65                     e.catch_exception(handler, Constants.TYPE_RUNTIME_EXCEPTION);
66                     e.athrow();
67                 }
68                 if (!exceptionSet.contains(Error JavaDoc.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 -> eo -> oeo -> ooe -> o
77
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 JavaDoc method = (Method JavaDoc)it.next();
91             EmitUtils.load_method(e, method);
92             e.putfield(getFieldName(context, method));
93         }
94     }
95 }
96
Popular Tags