1 8 9 15 package jfun.yan; 16 17 import java.lang.reflect.InvocationHandler ; 18 import java.lang.reflect.Method ; 19 import java.lang.reflect.Proxy ; 20 21 import jfun.yan.util.ReflectionUtil; 22 23 33 final class FactoryComponent<T> extends Component<T> { 34 private final Creator cc; 35 private final Class <T> factory_class; 36 private final ClassLoader loader; 37 private final String text; 38 private interface SerializableInvocationHandler 39 extends InvocationHandler , java.io.Serializable {} 40 FactoryComponent(final Creator cc, final Class <T> factory_class, 41 final ClassLoader loader, String text) { 42 this.cc = cc; 43 this.factory_class = factory_class; 44 this.loader = loader; 45 this.text = text; 46 } 47 48 public Class <T> getType() { 49 return factory_class; 50 } 51 public boolean isConcrete(){ 52 return true; 53 } 54 public T create(final Dependency dep){ 55 final InvocationHandler handler = new SerializableInvocationHandler(){ 56 public Object invoke(Object proxy, Method mtd, Object [] args) 57 throws Throwable { 58 if(Object .class.equals(mtd.getDeclaringClass())){ 59 try{ 61 return mtd.invoke(FactoryComponent.this, args); 62 } 63 catch(java.lang.reflect.InvocationTargetException e){ 64 throw e.getTargetException(); 65 } 66 } 67 else{ 68 if(args==null || args.length==0){ 69 return cc.create(dep); 70 } 71 else{ 72 final Creator[] cargs = new Creator[args.length]; 73 for(int i=0; i<args.length; i++){ 74 cargs[i] = Components.value(args[i]); 75 } 76 82 90 final Dependency ndep = bindArgs(dep, cargs); 91 return cc.create(ndep); 92 } 93 } 94 } 95 }; 96 return (T)Proxy.newProxyInstance(loader, new Class []{factory_class}, 97 handler); 98 } 99 public Class verify(final Dependency dep){ 100 final Method [] mtds = factory_class.getMethods(); 101 final Component wildcard = Components.value(null); 102 for(int i=0; i<mtds.length; i++){ 103 final Method mtd = mtds[i]; 104 if(Object .class.equals(mtd.getDeclaringClass())){ 105 continue; 106 } 107 final Class [] ptypes = mtd.getParameterTypes(); 108 final Class rtype = mtd.getReturnType(); 109 final Dependency parametered = withParamTypes(dep, ptypes, wildcard); 110 final Class real_type = cc.verify(parametered); 111 if(!ReflectionUtil.isAssignableFrom(rtype, real_type)){ 112 throw new ReturnTypeMismatchException(rtype, real_type, mtd); 113 } 114 } 115 return getType(); 116 } 117 private static Dependency bindArgs(Dependency dep, Creator[] args){ 118 return Components.bindArguments(dep, Components.getParameterBinder(args)); 119 } 120 private static Dependency withParamTypes( 121 final Dependency dep, final Class [] ptypes, final Component wildcard){ 122 if(ptypes==null || ptypes.length==0) return dep; 123 final Creator[] args = new Creator[ptypes.length]; 124 for(int i=0; i<args.length; i++){ 125 args[i] = wildcard.cast(ptypes[i]); 126 } 127 return bindArgs(dep, args); 128 } 129 public boolean equals(Object obj) { 130 if(obj instanceof FactoryComponent){ 131 final FactoryComponent other = (FactoryComponent)obj; 132 return factory_class.equals(other.factory_class) 133 && cc.equals(other.cc); 134 } 135 else return false; 136 } 137 public int hashCode() { 138 return factory_class.hashCode()*31+cc.hashCode(); 139 } 140 public String toString() { 141 return text; 143 } 144 public boolean isSingleton(){ 145 return false; 146 } 147 } 148 | Popular Tags |