KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > soto > reflect > Matcher


1 package org.sapia.soto.reflect;
2
3 import org.sapia.soto.util.Utils;
4 import org.sapia.soto.util.matcher.*;
5
6 import java.lang.reflect.Method JavaDoc;
7 import java.lang.reflect.Modifier JavaDoc;
8
9 import java.util.ArrayList JavaDoc;
10 import java.util.List JavaDoc;
11
12
13 /**
14  * A utility class that is used to perform method-matching operations.
15  * <pre>
16  * Matcher m = new Matcher();
17  * m.setName("set*");
18  * m.setSig("java.lang.String");
19  * List methods = m.scan(Class.forName("org.acme.SomeClass"));
20  * </pre>
21  *
22  * @author Yanick Duchesne
23  * <dl>
24  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
25  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
26  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
27  * </dl>
28  */

29 public class Matcher {
30   public static final String JavaDoc MODIFIER_PUBLIC = "public";
31   public static final String JavaDoc MODIFIER_PROTECTED = "protected";
32   public static final String JavaDoc MODIFIER_PRIVATE = "private";
33   private Pattern _namePattern;
34   private List JavaDoc _includes;
35   private List JavaDoc _excludes;
36   private List JavaDoc _sigPatterns;
37   private int _modifiers;
38   private boolean _ignoreCase;
39   private boolean _declared;
40
41   /**
42    * Constructor for BaseMatcher.
43    */

44   public Matcher() {
45     super();
46     _modifiers = _modifiers | Modifier.PUBLIC;
47     _modifiers = _modifiers | Modifier.PROTECTED;
48     _modifiers = _modifiers | Modifier.PRIVATE;
49   }
50
51   /**
52    * Specifies if this instance must perform case insensitive method name matching or not.
53    *
54    * @param ignoreCase if <code>true</code>, this instance will ignore method name case when
55    * matching.
56    */

57   public void setIgnoreCase(boolean ignoreCase) {
58     _ignoreCase = ignoreCase;
59   }
60
61   /**
62    * Sets the name pattern of the method(s) to match.
63    *
64    * @param name a name pattern.
65    */

66   public void setName(String JavaDoc name) {
67     _namePattern = PathPattern.parse(name, _ignoreCase);
68   }
69
70   /**
71    * Specifies if this instance will match against the declared methods of passed
72    * in classes.
73    *
74    * @param declared if <code>true</code>, specifies that this instance
75    * will match against the declared methods (not methods of the superclass) of
76    * the <code>Class</code> objects that it receives.
77    */

78   public void setDeclaredMethods(boolean declared) {
79     _declared = declared;
80   }
81
82   /**
83    * Determines the visibility of the matched method (must be "public", "protected"
84    * and/or "private".
85    *
86    * @param modifierList a comma-delimited list of access modifiers.
87    */

88   public void setVisibility(String JavaDoc modifierList) {
89     _modifiers = 0;
90
91     String JavaDoc[] modifiers = Utils.split(modifierList, ',', true);
92
93     for (int i = 0; i < modifiers.length; i++) {
94       if (modifiers[i].equalsIgnoreCase(MODIFIER_PUBLIC)) {
95         _modifiers = _modifiers | Modifier.PUBLIC;
96       } else if (modifiers[i].equalsIgnoreCase(MODIFIER_PROTECTED)) {
97         _modifiers = _modifiers | Modifier.PROTECTED;
98       } else if (modifiers[i].equalsIgnoreCase(MODIFIER_PRIVATE)) {
99         _modifiers = _modifiers | Modifier.PRIVATE;
100       } else {
101         throw new IllegalArgumentException JavaDoc("Unknown modifier: " + modifiers[i]);
102       }
103     }
104   }
105
106   /**
107    * @param classNames a comma-delimited list of class names whose methods
108    * are matched by this instance should be included.
109    */

110   public void setIncludes(String JavaDoc classNames) {
111     _includes = new ArrayList JavaDoc();
112
113     String JavaDoc[] classNamePatterns = Utils.split(classNames.trim(), ',', true);
114
115     for (int i = 0; i < classNamePatterns.length; i++) {
116       _includes.add(PathPattern.parse(classNamePatterns[i], _ignoreCase));
117     }
118   }
119
120   /**
121    * @param classNames a comma-delimited list of class names whose methods
122    * are matched by this instance should be excluded.
123    */

124   public void setExcludes(String JavaDoc classNames) {
125     _excludes = new ArrayList JavaDoc();
126
127     String JavaDoc[] classNamePatterns = Utils.split(classNames.trim(), ',', true);
128
129     for (int i = 0; i < classNamePatterns.length; i++) {
130       _excludes.add(PathPattern.parse(classNamePatterns[i], _ignoreCase));
131     }
132   }
133
134   /**
135    * Sets this instance's method signature pattern. If not specified, methods
136    * with any pattern will match.
137    *
138    * @param sig a method signature pattern.
139    */

140   public void setSig(String JavaDoc sig) {
141     if (sig.trim().length() == 0) {
142       _sigPatterns = new ArrayList JavaDoc();
143     } else {
144       String JavaDoc[] sigStr = Utils.split(sig, ',', true);
145       _sigPatterns = new ArrayList JavaDoc(sigStr.length);
146
147       for (int i = 0; i < sigStr.length; i++) {
148         _sigPatterns.add(PathPattern.parse(sigStr[i], _ignoreCase));
149       }
150     }
151   }
152
153   /**
154    * Peforms matching. Returns the list of matched method objects.
155    *
156    * @param clazz a <code>Class</code> instance to instrospect.
157    * @return a <code>List</code> of <code>Method</code>s.
158    */

159   public List JavaDoc scanMethods(Class JavaDoc clazz) {
160     Method JavaDoc[] meths;
161
162     if (_declared) {
163       meths = clazz.getDeclaredMethods();
164     } else {
165       meths = clazz.getMethods();
166     }
167
168     Class JavaDoc[] params;
169     List JavaDoc scanned = new ArrayList JavaDoc();
170     Pattern sigPattern;
171
172     for (int i = 0; i < meths.length; i++) {
173       if (((meths[i].getModifiers() & Modifier.PUBLIC) != 0) &&
174             ((_modifiers & Modifier.PUBLIC) == 0)) {
175         continue;
176       } else if (((meths[i].getModifiers() & Modifier.PROTECTED) != 0) &&
177             ((_modifiers & Modifier.PROTECTED) == 0)) {
178         continue;
179       } else if (((meths[i].getModifiers() & Modifier.PRIVATE) != 0) &&
180             ((_modifiers & Modifier.PRIVATE) == 0)) {
181         continue;
182       }
183
184       if (!isIncluded(meths[i])) {
185         continue;
186       }
187
188       params = meths[i].getParameterTypes();
189
190       if (_sigPatterns == null) {
191         if (_namePattern == null) {
192           scanned.add(meths[i]);
193         } else if (_namePattern.matches(meths[i].getName())) {
194           scanned.add(meths[i]);
195         }
196
197         continue;
198       }
199
200       if (_sigPatterns.size() != params.length) {
201         continue;
202       }
203
204       int matchCount = 0;
205
206       for (int j = 0; j < params.length; j++) {
207         sigPattern = (Pattern) _sigPatterns.get(j);
208
209         if (sigPattern.matches(params[j].getName())) {
210           matchCount++;
211         }
212       }
213
214       if (matchCount == params.length) {
215         if (_namePattern == null) {
216           scanned.add(meths[i]);
217         } else if (_namePattern.matches(meths[i].getName())) {
218           scanned.add(meths[i]);
219         }
220       }
221     }
222
223     return scanned;
224   }
225
226   private boolean isIncluded(Method JavaDoc m) {
227     boolean included = false;
228
229     if (_includes != null) {
230       for (int i = 0; i < _includes.size(); i++) {
231         if (((Pattern) _includes.get(i)).matches(m.getDeclaringClass().getName())) {
232           included = true;
233
234           break;
235         }
236       }
237     } else {
238       included = true;
239     }
240
241     if (_excludes != null) {
242       for (int i = 0; i < _excludes.size(); i++) {
243         if (((Pattern) _excludes.get(i)).matches(m.getDeclaringClass().getName())) {
244           included = false;
245
246           break;
247         }
248       }
249     }
250
251     return included;
252   }
253 }
254
Popular Tags