1 /************************************************* 2 * Copyright (c) Shen Li. All rights reserved. * 3 * http://joyaop.sourceforge.net * 4 * -------------------------------------------- * 5 * Distributable under LGPL license. * 6 * See terms of license at gnu.org. * 7 ************************************************/ 8 package net.sf.joyaop.impl; 9 10 import net.sf.joyaop.framework.Pointcut; 11 import net.sf.joyaop.util.ClassUtils; 12 13 import java.lang.reflect.Method; 14 import java.util.regex.Pattern; 15 16 /*** 17 * @author Shen Li 18 */ 19 public abstract class Pointcuts { 20 public static Pointcut byRegexp(String classRegexp, String methodRegexp) { 21 return new Regexp(classRegexp, methodRegexp); 22 } 23 24 public static Pointcut byInterface(Class interfaceClass) { 25 return new Interface(interfaceClass); 26 } 27 28 public static Pointcut byInterface(String interfaceName) { 29 return byInterface(ClassUtils.loadClass(interfaceName)); 30 } 31 32 public static Pointcut byAnnotation(Class annotationClass) { 33 return new Annotation(annotationClass); 34 } 35 36 public static Pointcut byAnnotation(String annotationClassName) { 37 return byAnnotation(ClassUtils.loadClass(annotationClassName)); 38 } 39 40 public static Pointcut and(Pointcut p1, Pointcut p2) { 41 return new And(p1, p2); 42 } 43 44 public static Pointcut or(Pointcut p1, Pointcut p2) { 45 return new Or(p1, p2); 46 } 47 48 public static Pointcut not(Pointcut p) { 49 return new Not(p); 50 } 51 52 public static class And implements Pointcut { 53 private final Pointcut p1; 54 private final Pointcut p2; 55 56 public And(Pointcut p1, Pointcut p2) { 57 this.p1 = p1; 58 this.p2 = p2; 59 } 60 61 public boolean matches(Class clazz) { 62 return p1.matches(clazz) && p2.matches(clazz); 63 } 64 65 public boolean matches(Class clazz, Method method) { 66 return p1.matches(clazz, method) && p2.matches(clazz, method); 67 } 68 69 public boolean equals(Object object) { 70 if (this == object) { 71 return true; 72 } 73 if (!(object instanceof And)) { 74 return false; 75 } 76 And and = (And) object; 77 if (p1.equals(and.p1) && p2.equals(and.p2) || p1.equals(and.p2) && p2.equals(and.p1)) { 78 return true; 79 } 80 return false; 81 } 82 83 public int hashCode() { 84 return p1.hashCode() * 31 + p2.hashCode(); 85 } 86 } 87 88 public static class Interface implements Pointcut { 89 private final Class interfaceClass; 90 91 public Interface(Class interfaceClass) { 92 this.interfaceClass = interfaceClass; 93 } 94 95 public boolean matches(Class clazz) { 96 return (interfaceClass.isAssignableFrom(clazz)); 97 } 98 99 public boolean matches(Class clazz, Method method) { 100 if (!matches(clazz)) { 101 return false; 102 } 103 if (method.getDeclaringClass() == interfaceClass) { 104 return true; 105 } 106 try { 107 interfaceClass.getMethod(method.getName(), method.getParameterTypes()); 108 } catch (NoSuchMethodException e) { 109 return false; 110 } 111 return true; 112 } 113 114 public boolean equals(Object object) { 115 if (this == object) { 116 return true; 117 } 118 if (!(object instanceof Interface)) { 119 return false; 120 } 121 Interface intf = (Interface) object; 122 if (interfaceClass == intf.interfaceClass) { 123 return true; 124 } 125 return false; 126 } 127 128 public int hashCode() { 129 return interfaceClass.hashCode(); 130 } 131 } 132 133 public static class Not implements Pointcut { 134 private final Pointcut pointcut; 135 136 public Not(Pointcut pointcut) { 137 this.pointcut = pointcut; 138 } 139 140 public boolean matches(Class clazz) { 141 return !pointcut.matches(clazz); 142 } 143 144 public boolean matches(Class clazz, Method method) { 145 return !pointcut.matches(clazz, method); 146 } 147 148 public boolean equals(Object object) { 149 if (this == object) { 150 return true; 151 } 152 if (!(object instanceof Not)) { 153 return false; 154 } 155 Not not = (Not) object; 156 if (pointcut.equals(not.pointcut)) { 157 return true; 158 } 159 return false; 160 } 161 162 public int hashCode() { 163 return pointcut.hashCode(); 164 } 165 } 166 167 public static class Or implements Pointcut { 168 private final Pointcut p1; 169 private final Pointcut p2; 170 171 public Or(Pointcut p1, Pointcut p2) { 172 this.p1 = p1; 173 this.p2 = p2; 174 } 175 176 public boolean matches(Class clazz) { 177 return p1.matches(clazz) || p2.matches(clazz); 178 } 179 180 public boolean matches(Class clazz, Method method) { 181 return p1.matches(clazz, method) || p2.matches(clazz, method); 182 } 183 184 public boolean equals(Object object) { 185 if (this == object) { 186 return true; 187 } 188 if (!(object instanceof Or)) { 189 return false; 190 } 191 Or or = (Or) object; 192 if (p1.equals(or.p1) && p2.equals(or.p2) || p1.equals(or.p2) && p2.equals(or.p1)) { 193 return true; 194 } 195 return false; 196 } 197 198 public int hashCode() { 199 return p1.hashCode() * 31 + p2.hashCode(); 200 } 201 } 202 203 public static class Regexp implements Pointcut { 204 private Pattern classPattern; 205 private Pattern methodPattern; 206 207 public Regexp(String classRegexp, String methodRegexp) { 208 if (classRegexp == null) { 209 classRegexp = ".*"; 210 } 211 if (methodRegexp == null) { 212 methodRegexp = ".*"; 213 } 214 this.classPattern = Pattern.compile(classRegexp); 215 this.methodPattern = Pattern.compile(methodRegexp); 216 } 217 218 public boolean matches(Class clazz, Method method) { 219 return (matches(clazz) && methodPattern.matcher(method.getName()).matches()); 220 } 221 222 public boolean matches(Class clazz) { 223 return classPattern.matcher(clazz.getName()).matches(); 224 } 225 226 public boolean equals(Object object) { 227 if (this == object) { 228 return true; 229 } 230 if (!(object instanceof Regexp)) { 231 return false; 232 } 233 Regexp regexp = (Regexp) object; 234 if (classPattern.pattern().equals(regexp.classPattern.pattern()) 235 && methodPattern.pattern().equals(regexp.methodPattern.pattern())) { 236 return true; 237 } 238 return false; 239 } 240 241 public int hashCode() { 242 return classPattern.pattern().hashCode() * 31 + methodPattern.hashCode(); 243 } 244 } 245 246 /*** 247 * It's method annotaion actually 248 */ 249 public static class Annotation implements Pointcut { 250 private Class annotationClass; 251 252 public Annotation(Class annotationClass) { 253 this.annotationClass = annotationClass; 254 } 255 256 public boolean matches(Class clazz, Method method) { 257 return (method.getAnnotation(annotationClass) == null ? false : true); 258 } 259 260 public boolean matches(Class clazz) { 261 return true; 262 } 263 264 public boolean equals(Object object) { 265 if (this == object) { 266 return true; 267 } 268 if (!(object instanceof Annotation)) { 269 return false; 270 } 271 if (annotationClass == ((Annotation) object).annotationClass) { 272 return true; 273 } 274 return false; 275 } 276 277 public int hashCode() { 278 return annotationClass.hashCode(); 279 } 280 } 281 }