1 16 package net.sf.cglib.reflect; 17 18 import java.lang.reflect.*; 19 import net.sf.cglib.core.*; 20 import org.objectweb.asm.ClassVisitor; 21 import org.objectweb.asm.Type; 22 23 27 abstract public class ConstructorDelegate { 28 private static final ConstructorKey KEY_FACTORY = 29 (ConstructorKey)KeyFactory.create(ConstructorKey.class, KeyFactory.CLASS_BY_NAME); 30 31 interface ConstructorKey { 32 public Object newInstance(String declaring, String iface); 33 } 34 35 protected ConstructorDelegate() { 36 } 37 38 public static ConstructorDelegate create(Class targetClass, Class iface) { 39 Generator gen = new Generator(); 40 gen.setTargetClass(targetClass); 41 gen.setInterface(iface); 42 return gen.create(); 43 } 44 45 public static class Generator extends AbstractClassGenerator { 46 private static final Source SOURCE = new Source(ConstructorDelegate.class.getName()); 47 private static final Type CONSTRUCTOR_DELEGATE = 48 TypeUtils.parseType("net.sf.cglib.reflect.ConstructorDelegate"); 49 50 private Class iface; 51 private Class targetClass; 52 53 public Generator() { 54 super(SOURCE); 55 } 56 57 public void setInterface(Class iface) { 58 this.iface = iface; 59 } 60 61 public void setTargetClass(Class targetClass) { 62 this.targetClass = targetClass; 63 } 64 65 public ConstructorDelegate create() { 66 setNamePrefix(targetClass.getName()); 67 Object key = KEY_FACTORY.newInstance(iface.getName(), targetClass.getName()); 68 return (ConstructorDelegate)super.create(key); 69 } 70 71 protected ClassLoader getDefaultClassLoader() { 72 return targetClass.getClassLoader(); 73 } 74 75 public void generateClass(ClassVisitor v) { 76 setNamePrefix(targetClass.getName()); 77 78 final Method newInstance = ReflectUtils.findNewInstance(iface); 79 if (!newInstance.getReturnType().isAssignableFrom(targetClass)) { 80 throw new IllegalArgumentException ("incompatible return type"); 81 } 82 final Constructor constructor; 83 try { 84 constructor = targetClass.getDeclaredConstructor(newInstance.getParameterTypes()); 85 } catch (NoSuchMethodException e) { 86 throw new IllegalArgumentException ("interface does not match any known constructor"); 87 } 88 89 ClassEmitter ce = new ClassEmitter(v); 90 ce.begin_class(Constants.V1_2, 91 Constants.ACC_PUBLIC, 92 getClassName(), 93 CONSTRUCTOR_DELEGATE, 94 new Type[]{ Type.getType(iface) }, 95 Constants.SOURCE_FILE); 96 Type declaring = Type.getType(constructor.getDeclaringClass()); 97 EmitUtils.null_constructor(ce); 98 CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, 99 ReflectUtils.getSignature(newInstance), 100 ReflectUtils.getExceptionTypes(newInstance)); 101 e.new_instance(declaring); 102 e.dup(); 103 e.load_args(); 104 e.invoke_constructor(declaring, ReflectUtils.getSignature(constructor)); 105 e.return_value(); 106 e.end_method(); 107 ce.end_class(); 108 } 109 110 protected Object firstInstance(Class type) { 111 return ReflectUtils.newInstance(type); 112 } 113 114 protected Object nextInstance(Object instance) { 115 return instance; 116 } 117 } 118 } 119 | Popular Tags |