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