1 8 14 package jfun.yan; 15 16 import java.lang.reflect.InvocationHandler ; 17 import java.lang.reflect.Method ; 18 import java.lang.reflect.Proxy ; 19 20 import jfun.util.Misc; 21 import jfun.yan.factory.Factory; 22 23 29 final class InstanceProxy 30 implements java.lang.reflect.InvocationHandler , Factory{ 31 private final Class [] itfs; 32 private final ClassLoader loader; 33 private volatile Object v; 34 private final Factory factory; 35 private void set(Object obj){ 36 v = obj; 37 } 38 41 private InstanceProxy(Factory factory, Class [] itfs, ClassLoader cl, 42 Object v) { 43 this.factory = factory; 44 this.itfs = itfs; 45 this.loader = cl; 46 this.v = v ; 47 } 48 public synchronized Object create(){ 49 if(v==null){ 50 v = factory.create(); 51 } 52 return v; 53 } 54 public synchronized void clear(){ 55 v = null; 56 } 57 public synchronized Object invoke(Object proxy, Method mtd, Object [] args) 58 throws Throwable { 59 try{ 60 if(Object .class.equals(mtd.getDeclaringClass())){ 61 return mtd.invoke(this, args); 62 } 63 else{ 64 return mtd.invoke(create(), args); 65 } 66 } 67 catch(java.lang.reflect.InvocationTargetException e){ 68 throw e.getTargetException(); 69 } 70 } 71 static Object instance(ClassLoader cl, Class [] itfs, Factory factory){ 72 final Class [] myitfs = copy(itfs); 73 return Proxy.newProxyInstance(cl, 74 myitfs, new InstanceProxy(factory, myitfs, cl, null)); 75 } 76 static Class getProxyClass(ClassLoader cl, Class [] itfs){ 77 return Proxy.getProxyClass(cl, itfs); 78 } 79 private Object getComparisonTarget(Object other){ 80 if(other instanceof InstanceProxy){ 81 final InstanceProxy p2 = (InstanceProxy)other; 82 return p2.create(); 83 } 84 if(other instanceof Proxy ){ 85 return getComparisonTarget(Proxy.getInvocationHandler(other)); 86 } 87 return other; 88 } 89 public boolean equals(Object other) { 90 final Object v1 = create(); 91 final Object v2 = getComparisonTarget(other); 92 return v1==null?(v2==null):v1.equals(v2); 93 } 94 public int hashCode() { 95 final Object v1 = create(); 96 return v1==null?0:v1.hashCode(); 97 } 98 public String toString() { 99 return ""+create(); 100 } 101 static boolean setImplementation(Object proxy, Object obj){ 102 if(!Proxy.isProxyClass(proxy.getClass())) return false; 103 final InvocationHandler ih = Proxy.getInvocationHandler(proxy); 104 if(ih instanceof InstanceProxy){ 105 final InstanceProxy ip = (InstanceProxy)ih; 106 checkTypes(ip.itfs, obj); 107 ip.set(obj); 108 return true; 109 } 110 else return false; 111 } 112 static void clear(Object proxy){ 113 if(!Proxy.isProxyClass(proxy.getClass())) return; 114 final InvocationHandler ih = Proxy.getInvocationHandler(proxy); 115 if(ih instanceof InstanceProxy){ 116 final InstanceProxy ip = (InstanceProxy)ih; 117 ip.clear(); 118 } 119 } 120 private static Class [] copy(Class [] types){ 121 final Class [] ret = new Class [types.length]; 122 for(int i=0; i<types.length; i++){ 123 ret[i] = types[i]; 124 } 125 return ret; 126 } 127 private static void checkTypes(Class [] types, Object obj){ 128 for(int i=0; i<types.length; i++){ 129 final Class type = types[i]; 130 if(!type.isInstance(obj)){ 131 throw new IllegalArgumentException ("object of type " 132 + Misc.getTypeName(Utils.getObjType(obj)) 133 + " is not an instance of " + Misc.getTypeName(type)); 134 } 135 } 136 } 137 } 138 | Popular Tags |