View Javadoc
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