1 package net.sf.cglib.transform.impl;
2
3 import net.sf.cglib.transform.*;
4 import java.lang.reflect.*;
5 import java.util.*;
6 import net.sf.cglib.core.*;
7 import org.objectweb.asm.Attribute;
8 import org.objectweb.asm.Type;
9
10 /***
11 * @author Juozas Baliuka
12 */
13 public class AddDelegateTransformer extends ClassEmitterTransformer {
14 private static final String DELEGATE = "$CGLIB_DELEGATE";
15 private static final Signature CSTRUCT_OBJECT =
16 TypeUtils.parseSignature("void <init>(Object)");
17
18 private Class[] delegateIf;
19 private Class delegateImpl;
20 private Type delegateType;
21
22 /*** Creates a new instance of AddDelegateTransformer */
23 public AddDelegateTransformer(Class delegateIf[], Class delegateImpl) {
24 try {
25 delegateImpl.getConstructor(new Class[]{ Object.class });
26 this.delegateIf = delegateIf;
27 this.delegateImpl = delegateImpl;
28 delegateType = Type.getType(delegateImpl);
29 } catch (NoSuchMethodException e) {
30 throw new CodeGenerationException(e);
31 }
32 }
33
34 public void begin_class(int access, String className, Type superType, Type[] interfaces, String sourceFile) {
35
36 if(!TypeUtils.isInterface(access)){
37
38 Type[] all = TypeUtils.add(interfaces, TypeUtils.getTypes(delegateIf));
39 super.begin_class(access, className, superType, all, sourceFile);
40
41 declare_field(Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT,
42 DELEGATE,
43 delegateType,
44 null,
45 null);
46 for (int i = 0; i < delegateIf.length; i++) {
47 Method[] methods = delegateIf[i].getMethods();
48 for (int j = 0; j < methods.length; j++) {
49 if (Modifier.isAbstract(methods[j].getModifiers())) {
50 addDelegate(methods[j]);
51 }
52 }
53 }
54 }else{
55 super.begin_class(access, className, superType, interfaces, sourceFile);
56 }
57 }
58
59 public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions, Attribute attrs) {
60 final CodeEmitter e = super.begin_method(access, sig, exceptions, attrs);
61 if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) {
62 return new CodeEmitter(e) {
63 private boolean transformInit = true;
64 public void visitMethodInsn(int opcode, String owner, String name, String desc) {
65 super.visitMethodInsn(opcode, owner, name, desc);
66 if (transformInit && opcode == Constants.INVOKESPECIAL) {
67 load_this();
68 new_instance(delegateType);
69 dup();
70 load_this();
71 invoke_constructor(delegateType, CSTRUCT_OBJECT);
72 putfield(DELEGATE);
73 transformInit = false;
74 }
75 }
76 };
77 }
78 return e;
79 }
80
81 private void addDelegate(Method m) {
82 Method delegate;
83 try {
84 delegate = delegateImpl.getMethod(m.getName(), m.getParameterTypes());
85 if (!delegate.getReturnType().getName().equals(m.getReturnType().getName())){
86 throw new IllegalArgumentException("Invalid delegate signature " + delegate);
87 }
88 } catch (NoSuchMethodException e) {
89 throw new CodeGenerationException(e);
90 }
91
92 final Signature sig = ReflectUtils.getSignature(m);
93 Type[] exceptions = TypeUtils.getTypes(m.getExceptionTypes());
94 CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, sig, exceptions, null);
95 e.load_this();
96 e.getfield(DELEGATE);
97 e.load_args();
98 e.invoke_virtual(delegateType, sig);
99 e.return_value();
100 e.end_method();
101 }
102 }
103
104
105
This page was automatically generated by Maven