1 package jfun.yan.etc; 2 3 import java.lang.reflect.InvocationHandler ; 4 import java.lang.reflect.Method ; 5 import java.lang.reflect.Proxy ; 6 7 import jfun.yan.Mutation; 8 9 19 public final class InjectingProxy implements InvocationHandler { 20 private final Mutation injector; 21 private final Class target_type; 22 private final Object proxied; 23 24 private InjectingProxy(Object proxied, Class target_type, Mutation injector) { 25 this.injector = injector; 26 this.proxied = proxied; 27 this.target_type = target_type; 28 } 29 public Object invoke(Object proxy, Method mtd, Object [] args) 30 throws Throwable { 31 if(Object .class.equals(mtd.getDeclaringClass())){ 32 return mtd.invoke(this, args); 33 } 34 else{ 35 final Object r = mtd.invoke(proxied, args); 36 if(target_type.isInstance(r)){ 37 injector.mutate(r); 39 } 40 return r; 41 } 42 } 43 public boolean equals(Object obj) { 44 if(obj == null) return false; 45 if(Proxy.isProxyClass(obj.getClass())){ 46 obj = Proxy.getInvocationHandler(obj); 47 } 48 if(obj instanceof InjectingProxy){ 49 final InjectingProxy other = (InjectingProxy)obj; 50 return proxied.equals(other.proxied); 51 } 52 else return proxied.equals(obj); 53 } 54 public int hashCode() { 55 return proxied.hashCode(); 56 } 57 public String toString() { 58 return proxied.toString(); 59 } 60 70 public static Object getInjectingProxy(ClassLoader cloader, Class [] itfs, 71 Object proxied, Class injectee_type, Mutation injector){ 72 return Proxy.newProxyInstance(cloader, itfs, 73 new InjectingProxy(proxied, injectee_type, injector)); 74 } 75 85 public static Object getInjectingProxy(ClassLoader cloader, Class itf, 86 Object proxied, Class injectee_type, Mutation injector){ 87 return getInjectingProxy(cloader, new Class []{itf}, proxied, injectee_type, injector); 88 } 89 101 public static Object getInjectingProxy(Class itf, Object proxied, Class injectee_type, Mutation injector){ 102 return getInjectingProxy(proxied.getClass().getClassLoader(), itf, proxied, injectee_type, injector); 103 } 104 115 public static Object getInjectingProxy(Object proxied, Class injectee_type, Mutation injector){ 116 final Class [] itfs = proxied.getClass().getInterfaces(); 117 return getInjectingProxy(proxied.getClass().getClassLoader(), itfs, 118 proxied, injectee_type, injector); 119 } 120 121 } 122 | Popular Tags |