View Javadoc

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 }