1 package dynaop; 2 3 import java.lang.reflect.Method ; 4 import java.util.Collections ; 5 import java.util.Map ; 6 import java.util.WeakHashMap ; 7 8 import org.apache.oro.text.regex.MalformedPatternException; 9 import org.apache.oro.text.regex.Pattern; 10 import org.apache.oro.text.regex.Perl5Compiler; 11 import org.apache.oro.text.regex.Perl5Matcher; 12 13 18 public class Pointcuts { 19 20 Pointcuts() {} 21 22 25 public static final ClassPointcut ALL_CLASSES = new ClassPointcut() { 26 public boolean picks(Class clazz) { 27 return true; 28 } 29 }; 30 31 34 public static final MethodPointcut ALL_METHODS = new MethodPointcut() { 35 public boolean picks(Method method) { 36 return true; 37 } 38 }; 39 40 44 public static final MethodPointcut OBJECT_METHODS = declaringClass( 45 singleton(Object .class)); 46 47 50 public static final MethodPointcut GET_METHODS = 51 new PropertyMethodPointcut("get"); 52 53 56 public static final MethodPointcut IS_METHODS = 57 new PropertyMethodPointcut("is"); 58 59 62 public static final MethodPointcut SET_METHODS = 63 new PropertyMethodPointcut("set"); 64 65 68 public static ClassPointcut packageName(final String packageName) { 69 return new ClassPointcut() { 70 public boolean picks(Class clazz) { 71 return clazz.getPackage().getName().equals(packageName); 72 } 73 }; 74 } 75 76 79 public static ClassPointcut union(final ClassPointcut a, 80 final ClassPointcut b) { 81 return new ClassPointcut() { 82 public boolean picks(Class clazz) { 83 return a.picks(clazz) || b.picks(clazz); 84 } 85 }; 86 } 87 88 91 public static MethodPointcut union(final MethodPointcut a, 92 final MethodPointcut b) { 93 return new MethodPointcut() { 94 public boolean picks(Method method) { 95 return a.picks(method) || b.picks(method); 96 } 97 }; 98 } 99 100 103 public static ClassPointcut intersection(final ClassPointcut a, 104 final ClassPointcut b) { 105 return new ClassPointcut() { 106 public boolean picks(Class clazz) { 107 return a.picks(clazz) && b.picks(clazz); 108 } 109 }; 110 } 111 112 115 public static MethodPointcut intersection(final MethodPointcut a, 116 final MethodPointcut b) { 117 return new MethodPointcut() { 118 public boolean picks(Method method) { 119 return a.picks(method) && b.picks(method); 120 } 121 }; 122 } 123 124 128 public static ClassPointcut className(String regex) 129 throws MalformedPatternException { 130 Perl5Compiler compiler = new Perl5Compiler(); 131 final Pattern compiled = compiler.compile(regex); 132 final Perl5Matcher matcher = new Perl5Matcher(); 133 return new ClassPointcut() { 134 public boolean picks(Class clazz) { 135 return matcher.contains(clazz.getName(), compiled); 136 } 137 }; 138 } 139 140 152 public static MethodPointcut signature(String regex) 153 throws MalformedPatternException { 154 Perl5Compiler compiler = new Perl5Compiler(); 155 final Pattern compiled = compiler.compile(regex); 156 final Perl5Matcher matcher = new Perl5Matcher(); 157 return new MethodPointcut() { 158 public boolean picks(Method method) { 159 return matcher.contains(methodToString(method), compiled); 160 } 161 }; 162 } 163 164 167 public static ClassPointcut instancesOf(final Class parent) { 168 return new ClassPointcut() { 169 public boolean picks(Class clazz) { 170 return parent.isAssignableFrom(clazz); 171 } 172 }; 173 } 174 175 178 public static ClassPointcut singleton(final Class c) { 179 return new ClassPointcut() { 180 public boolean picks(Class clazz) { 181 return clazz.equals(c); 182 } 183 }; 184 } 185 186 189 public static MethodPointcut singleton(final Method m) { 190 return new MethodPointcut() { 191 public boolean picks(Method method) { 192 return method.equals(m); 193 } 194 }; 195 } 196 197 200 public static ClassPointcut not(final ClassPointcut a) { 201 return new ClassPointcut() { 202 public boolean picks(Class clazz) { 203 return !a.picks(clazz); 204 } 205 }; 206 } 207 208 211 public static MethodPointcut not(final MethodPointcut a) { 212 return new MethodPointcut() { 213 public boolean picks(Method method) { 214 return !a.picks(method); 215 } 216 }; 217 } 218 219 223 public static MethodPointcut declaringClass( 224 final ClassPointcut classPointcut) { 225 return new MethodPointcut() { 226 public boolean picks(Method method) { 227 return classPointcut.picks(method.getDeclaringClass()); 228 } 229 }; 230 } 231 232 236 public static MethodPointcut returnType( 237 final ClassPointcut classPointcut) { 238 return new MethodPointcut() { 239 public boolean picks(Method method) { 240 return classPointcut.picks(method.getReturnType()); 241 } 242 }; 243 } 244 245 249 public static MethodPointcut membersOf(final Class clazz) { 250 return new MethodPointcut() { 251 public boolean picks(Method method) { 252 try { 253 clazz.getMethod(method.getName(), 254 method.getParameterTypes()); 255 return true; 256 } 257 catch (NoSuchMethodException e) { 258 return false; 259 } 260 } 261 }; 262 } 263 264 static String getTypeName(Class clazz) { 265 String name = clazz.getName(); 266 return (name.startsWith("java.lang.")) ? name.substring(10) : name; 267 } 268 269 static Map methodSignatureCache = 270 Collections.synchronizedMap(new WeakHashMap ()); 271 272 static String methodToString(Method method) { 273 String signature = (String ) methodSignatureCache.get(method); 274 if (signature != null) 275 return signature; 276 277 StringBuffer buffer = new StringBuffer (); 278 buffer.append(getTypeName(method.getReturnType())); 279 buffer.append(' '); 280 buffer.append(method.getName()); 281 282 buffer.append('('); 283 boolean first = true; 284 Class [] types = method.getParameterTypes(); 285 for (int i = 0; i < types.length; i++) { 286 if (!first) 287 buffer.append(", "); 288 first = false; 289 buffer.append(getTypeName(types[i])); 290 } 291 buffer.append(')'); 292 293 Class [] exceptions = method.getExceptionTypes(); 294 if (exceptions.length > 0) { 295 first = true; 296 buffer.append(" throws "); 297 for (int i = 0; i < exceptions.length; i++) { 298 if (!first) 299 buffer.append(", "); 300 first = false; 301 buffer.append(getTypeName(exceptions[i])); 302 } 303 } 304 305 signature = buffer.toString(); 306 methodSignatureCache.put(method, signature); 307 return signature; 308 } 309 310 static class PropertyMethodPointcut implements MethodPointcut { 311 312 private String prefix; 313 314 PropertyMethodPointcut(String prefix) { 315 this.prefix = prefix; 316 } 317 318 public boolean picks(Method method) { 319 String name = method.getName(); 320 return (name.length() > prefix.length() && 321 Character.isUpperCase(name.charAt(prefix.length())) && 322 name.startsWith(prefix)); 323 } 324 } 325 } 326 | Popular Tags |