1 package dynaop; 2 3 import java.io.IOException ; 4 import java.io.ObjectInputStream ; 5 import java.io.ObjectOutputStream ; 6 import java.io.Serializable ; 7 import java.lang.reflect.Method ; 8 import java.util.HashMap ; 9 import java.util.Map ; 10 11 import dynaop.util.*; 12 import dynaop.util.ArrayObject; 13 14 19 abstract class ProxyInvocationHandler implements ProxyContext, Serializable { 20 21 static Interceptor[] NO_INTERCEPTORS = new Interceptor[0]; 22 23 static long serialVersionUID = 0; 24 25 ProxyType proxyType; 26 Proxy proxy; 27 28 Map factoryToInterceptor = new HashMap (); 29 Map interceptors; 30 31 ProxyInvocationHandler(ProxyType proxyType) { 32 this.proxyType = proxyType; 33 34 try { 35 interceptors = (Map ) mapClass.newInstance(); 36 } 37 catch (Exception e) { 38 throw NestedException.wrap(e); 39 } 40 } 41 42 45 void setProxy(Proxy proxy) { 46 this.proxy = proxy; 47 } 48 49 52 Interceptor createInterceptor(InterceptorFactory factory) { 53 Interceptor interceptor = 54 (Interceptor) factoryToInterceptor.get(factory); 55 if (interceptor == null) { 56 interceptor = factory.create(this.getProxy()); 57 factoryToInterceptor.put(factory, interceptor); 58 } 59 return interceptor; 60 } 61 62 65 Interceptor[] createInterceptors(Object proxy, 66 InterceptorFactory[] factories) { 67 if (factories == null) 68 return NO_INTERCEPTORS; 69 70 Interceptor[] chain = new Interceptor[factories.length]; 71 for (int i = 0; i < factories.length; i++) 72 chain[i] = createInterceptor(factories[i]); 73 74 return chain; 75 } 76 77 class GetProxyContextInterceptor implements Interceptor, Serializable { 78 public Object intercept(Invocation invocation) throws Throwable { 79 return ProxyInvocationHandler.this; 80 } 81 } 82 83 87 synchronized Interceptor[] getInternalInterceptors(Method method) { 88 Interceptor[] chain = (Interceptor[]) this.interceptors.get(method); 89 90 if (chain == null) { 91 if (method.getDeclaringClass().equals(Proxy.class)) { 92 chain = new Interceptor[] { new GetProxyContextInterceptor() }; 93 } 94 else { 95 chain = createInterceptors( 96 proxy, this.proxyType.getInterceptorFactories(method)); 97 } 98 99 this.interceptors.put(method, chain); 100 } 101 102 return chain; 103 } 104 105 Object invoke(Object proxy, Object target, Method method, 106 Object [] arguments) throws Throwable { 107 Interceptor[] interceptors = getInternalInterceptors(method); 108 109 if (interceptors.length == 0) 110 return InvocationImpl.invokeTarget(proxy, target, method, arguments, 111 isClassProxy()); 112 113 InvocationImpl invocation = new InvocationImpl(); 114 115 invocation.setTarget(target); 116 invocation.setProxy((Proxy) proxy); 117 invocation.setMethod(method); 118 invocation.setArguments(arguments); 119 invocation.setInterceptors(interceptors); 120 invocation.setClassProxy(isClassProxy()); 121 122 return invocation.proceed(); 123 } 124 125 129 private void writeObject(ObjectOutputStream out) 130 throws IOException { 131 out.writeObject(proxyType); 132 out.writeObject(getHandle()); 133 out.writeObject(factoryToInterceptor); 134 out.writeObject(MethodHandle.handleMethodKeys(this.interceptors)); 135 } 136 137 private void readObject(ObjectInputStream in) 138 throws ClassNotFoundException , IOException { 139 this.proxyType = (ProxyType) in.readObject(); 140 this.proxy = ((Handle) in.readObject()).getProxy(); 141 this.factoryToInterceptor = (Map ) in.readObject(); 142 this.interceptors = MethodHandle.unhandleMethodKeys( 143 (Map ) in.readObject()); 144 } 145 146 150 public Interceptor[] getInterceptors(Method method) { 151 return (Interceptor[]) ArrayObject.clone( 152 getInternalInterceptors(method)); 153 } 154 155 public Proxy getProxy() { 156 return this.proxy; 157 } 158 159 public ProxyType getProxyType() { 160 return this.proxyType; 161 } 162 163 Handle handle; 164 165 public final synchronized Handle getHandle() { 166 if (this.handle == null) 167 this.handle = createHandle(); 168 return this.handle; 169 } 170 171 protected abstract Handle createHandle(); 172 173 static Class mapClass = HashMap .class; 175 static { 176 try { 177 mapClass = Class.forName("java.util.IdentityHashMap"); 178 } 179 catch (ClassNotFoundException e) {} 180 } 181 } 182 | Popular Tags |