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.ArrayList ; 9 import java.util.Arrays ; 10 import java.util.Collections ; 11 import java.util.HashMap ; 12 import java.util.HashSet ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 import dynaop.util.*; 19 import dynaop.util.Classes; 20 import dynaop .util.Closure; 21 22 27 class ProxyTypeBuilder { 28 29 private List interfaces = new ArrayList (); 30 private Map interceptorFactories = new HashMap (); 31 private Class proxiedClass; 32 33 ProxyTypeBuilder(Class proxiedClass) { 34 this.proxiedClass = proxiedClass; 35 36 List classes = Classes.getAllInterfacesAsList(proxiedClass); 37 classes.removeAll(Aspects.IGNORED_INTERFACES); 38 this.interfaces.addAll(classes); 39 } 40 41 44 public ProxyType createProxyType() { 45 return new ProxyTypeImpl(this); 46 } 47 48 51 boolean isEmpty() { 52 return this.interceptorFactories.isEmpty(); 53 } 54 55 57 62 public List getInterfaces() { 63 return Collections.unmodifiableList(this.interfaces); 64 } 65 66 69 public void addInterfaces(List interfaces) { 70 List added = new ArrayList (interfaces); 71 added.removeAll(this.interfaces); 72 added.remove(Object .class); 73 this.interfaces.addAll(added); 74 } 75 76 79 public void addInterfaces(Class [] interfaces) { 80 addInterfaces(Arrays.asList(interfaces)); 81 } 82 83 86 public void addInterface(Class clazz) { 87 if (clazz == null) 88 throw new NullPointerException (); 89 if (clazz == Object .class) 90 return; 91 this.interfaces.add(clazz); 92 } 93 94 96 102 public List getInterceptorFactories(Method method) { 103 return (List ) this.interceptorFactories.get(method); 104 } 105 106 109 List getInterceptorFactoriesForAddition(Method method) { 110 List interceptors = (List ) this.interceptorFactories.get(method); 111 if (interceptors == null) { 112 interceptors = new ArrayList (); 113 this.interceptorFactories.put(method, interceptors); 114 } 115 return interceptors; 116 } 117 118 121 public void addInterceptorFactory(Method method, 122 InterceptorFactory factory) { 123 getInterceptorFactoriesForAddition(method).add(factory); 124 } 125 126 129 public void addInterceptorFactory(InterceptorFactory factory) { 130 addInterceptorFactory(Pointcuts.ALL_METHODS, factory); 131 } 132 133 136 public void addInterceptorFactory(Class [] interfaces, 137 InterceptorFactory factory) { 138 if (factory == null) 139 throw new NullPointerException ("Factory is null."); 140 141 Set visitedMethods = new HashSet (); 142 for (int i = 0; i < interfaces.length; i++) { 143 Method [] methods = interfaces[i].getMethods(); 144 for (int methodIndex = 0; methodIndex < methods.length; 145 methodIndex++) { 146 Method method = methods[methodIndex]; 147 if (visitedMethods.contains(method)) 148 continue; 149 visitedMethods.add(method); 150 addInterceptorFactory(method, factory); 151 } 152 } 153 } 154 155 158 public void addInterceptorFactory(final MethodPointcut methodPointcut, 159 final InterceptorFactory factory) { 160 if (factory == null) 161 throw new NullPointerException ("Factory is null."); 162 163 execute(new Closure() { 164 public void execute(Object o) { 165 Method method = (Method ) o; 166 if (methodPointcut.picks(method)) 167 addInterceptorFactory(method, factory); 168 } 169 }); 170 } 171 172 176 void execute(Closure closure) { 177 Set visited = new HashSet (); 179 180 Method [] methods = Classes.OBJECT_METHODS; 181 for (int i = 0; i < methods.length; i++) { 182 Method m = methods[i]; 183 visited.add(m); 184 closure.execute(m); 185 } 186 187 methods = getProxiedClass().getMethods(); 188 for (int i = 0; i < methods.length; i++) { 189 Method m = methods[i]; 190 visited.add(m); 191 if (m.getDeclaringClass().equals(Object .class)) 192 continue; 193 closure.execute(m); 194 } 195 196 for (Iterator iterator = this.interfaces.iterator(); 197 iterator.hasNext();) { 198 Class clazz = (Class ) iterator.next(); 199 200 methods = clazz.getMethods(); 201 for (int i = 0; i < methods.length; i++) { 202 if (visited.contains(methods[i])) 203 continue; 204 visited.add(methods[i]); 205 closure.execute(methods[i]); 206 } 207 } 208 } 209 210 public String toString() { 211 StringBuffer buffer = new StringBuffer (); 212 buffer.append("ProxyTypeBuilder["); 213 buffer.append("interfaces: "); 214 buffer.append(this.interfaces); 215 buffer.append(", interceptors: "); 216 buffer.append(this.interceptorFactories); 217 buffer.append("]"); 218 return buffer.toString(); 219 } 220 221 Class getProxiedClass() { 222 return proxiedClass; 223 } 224 225 static class ProxyTypeImpl implements ProxyType, Serializable { 226 227 static long serialVersionUID = 0; 228 229 Class [] interfaces; 230 transient Map interceptorFactories; 231 232 ProxyTypeImpl(ProxyTypeBuilder builder) { 233 this.interfaces = 234 (Class []) builder.interfaces.toArray( 235 new Class [builder.interfaces.size()]); 236 237 this.interceptorFactories = new HashMap (); 239 for (Iterator i = builder.interceptorFactories.entrySet().iterator(); 240 i.hasNext();) { 241 Map.Entry entry = (Map.Entry ) i.next(); 242 List list = (List ) entry.getValue(); 243 this.interceptorFactories.put( 244 entry.getKey(), 245 list.toArray(new InterceptorFactory[list.size()]) 246 ); 247 } 248 } 249 250 public Class [] getInterfaces() { 251 return this.interfaces; 252 } 253 254 public InterceptorFactory[] getInterceptorFactories(Method method) { 255 return (InterceptorFactory[]) this.interceptorFactories.get(method); 256 } 257 258 public String toString() { 259 StringBuffer buffer = new StringBuffer (); 260 261 buffer.append("ProxyType["); 262 263 buffer.append("interfaces: "); 264 buffer.append(Arrays.asList(this.interfaces)); 265 266 buffer.append(", interceptorFactories: "); 267 Map map = new HashMap (); 268 for (Iterator i = this.interceptorFactories.entrySet().iterator(); 269 i.hasNext();) { 270 Map.Entry entry = (Map.Entry ) i.next(); 271 map.put( 272 entry.getKey(), 273 Arrays.asList((Object []) entry.getValue()) 274 ); 275 } 276 buffer.append(map); 277 278 buffer.append("]"); 279 280 return buffer.toString(); 281 } 282 283 private void writeObject(ObjectOutputStream out) 284 throws IOException { 285 out.defaultWriteObject(); 286 out.writeObject( 287 MethodHandle.handleMethodKeys(this.interceptorFactories)); 288 } 289 290 private void readObject(ObjectInputStream in) 291 throws ClassNotFoundException , IOException { 292 in.defaultReadObject(); 293 this.interceptorFactories = MethodHandle.unhandleMethodKeys( 294 (Map ) in.readObject()); 295 } 296 } 297 } 298 | Popular Tags |