/Users/lyon/j4p/src/classUtils/reflection/MethodList.java
|
1 package classUtils.reflection;
2
3 import collections.sortable.SortableVector;
4 import security.WebStartBean;
5 import utils.StringUtils;
6
7 import java.lang.reflect.Field;
8 import java.lang.reflect.Method;
9 import java.lang.reflect.Modifier;
10 import java.util.Vector;
11
12 /**
13 * methodList is a container and processor of methods.
14 */
15 public class MethodList {
16 private java.util.Vector v = new java.util.Vector();
17
18 public MethodList(Class c) {
19 java.lang.reflect.Method ma[] = c.getMethods();
20 for (int i = 0; i < ma.length; i++)
21 if (ma[i].getDeclaringClass() != Object.class)
22 v.addElement(ma[i]);
23 }
24 public boolean hasMainMethod() {
25 Method m[] = getMainMethods();
26 return m.length != 0;
27 }
28 /**
29 * Get a list of all methods that might be
30 * considered a main method
31 *
32 * @return method list
33 */
34 public Method[] getMainMethods() {
35 Method allMethods[] = getMethods();
36 Vector mainMethods = new Vector();
37 for (int i = 0;
38 i < allMethods.length;
39 i++) {
40 Method m = allMethods[i];
41 String methodString = m.toString();
42 if ((-1 ==
43 methodString.indexOf("public"))) continue;
44 if ((-1 ==
45 methodString.indexOf("static"))) continue;
46
47 if (!m.getName().equals("main")) continue;
48
49 String returnType = m.getReturnType()
50 .toString();
51 if (!returnType.equals("void")) continue;
52 Class params[] = m.getParameterTypes();
53 if (params.length != 1) continue;
54 Class firstParam = params[0];
55 String args[] = {"hi", "there"};
56 Class argsArray = args.getClass();
57 if (!argsArray.toString().equals(
58 "class [Ljava.lang.String;"))
59 continue;
60 mainMethods.addElement(m);
61 }
62 Method ma[] = new Method[mainMethods.size()];
63 mainMethods.copyInto(ma);
64 return ma;
65 }
66
67 public static void main(String[] args) {
68 WebStartBean wsb = WebStartBean.getDefaultWebStartBean();
69 MethodList ml = new MethodList(wsb.getClass());
70 Method m[] = ml.getReadWriteMethods();
71 for (int i = 0; i < m.length; i++)
72 System.out.println(m[i]);
73 }
74
75 public MethodList() {
76 }
77
78 /**
79 * @param setter - given the <code>setter </code>
80 * @return the <code>getter</code>.
81 */
82 public Method getReadMethod(Method setter) {
83 String propertyName = getPropertyName(setter);
84 Method ma[] = getReadMethods();
85 for (int i = 0; i < ma.length; i++)
86 if (propertyName.equals(getPropertyName(ma[i]))) return ma[i];
87 return null;
88 }
89
90 public static Method[] getPrimMethods(MethodList ml) {
91 Method m[] = ml.getWriteMethods();
92 Vector v = new Vector();
93 for (int i = 0; i < m.length; i++) {
94 Method m1 = m[i];
95 if (isAcceptableParamList(m1))
96 v.addElement(m1);
97 }
98 Method newArray[] = new Method[v.size()];
99 v.copyInto(newArray);
100 return newArray;
101 }
102
103 public int index(java.lang.reflect.Method m1) {
104 for (int i = 0; i < v.size(); i++) {
105 java.lang.reflect.Method m2 = elementAt(i);
106 if (equals(m1, m2))
107 return i;
108 }
109 return -1;
110 }
111
112 public static boolean isAcceptableParamList(Method m) {
113 Class c[] = m.getParameterTypes();
114 for (int i = 0; i < c.length; i++) {
115 if ((!c[i].isPrimitive()) &&
116 (!c[i].equals(String.class)))
117 return false;
118 }
119 return true;
120 }
121 // How would you build a CLI for a method
122 // that takes arguments?
123 // For example:
124 // run() is different from run(arg1, arg2);
125 // 1. Extract the method name.
126 // 2. Extract the arguments.
127 // public void run();
128 // public void run(String s1, String s2);
129 // It is clear that:
130 // run(arg1, arg2) -> public void run(String s1, String s2)
131 // public void run(int i1, int i2);
132 // parse(String commandLine) ....
133 // parse("run(12,13)");
134 // PR1 - Method name preceedes ()'s.
135 // PR2 - Args are in ()'s.
136 // String args[] = {"12","13"};
137 // Args always come from the command line so
138 // main can always be invoked!
139
140 java.lang.reflect.Method[] getMethodsWithNArgs(int n) {
141 java.lang.reflect.Method m[] = getMethods();
142 return getMethodsWithNArgs(m, n);
143 }
144
145 public static Method[] getMethodsWithNArgs(Method[] m, int n) {
146 MethodList ml = new MethodList();
147 for (int i = 0; i < m.length; i++) {
148 Class ca[] = m[i].getParameterTypes();
149 if (ca.length == n)
150 ml.add(m[i]);
151 }
152 return ml.getMethods();
153 }
154
155 public String[] getPropertyNames() {
156 Method m[] = getWriteMethods();
157 SortableVector v = new SortableVector();
158 for (int i = 0; i < m.length; i++) {
159 v.addElement(getPropertyName(m[i]));
160 }
161 v.sort();
162 String s[] = new String[m.length];
163 v.copyInto(s);
164 return s;
165 }
166
167 public static String getPropertyName(Method m) {
168 String s = m.getName();
169 if (s.startsWith("set") || s.startsWith("get"))
170 s = s.substring(3);
171 else if (s.startsWith("is"))
172 s = s.substring(2);
173 StringBuffer sb = StringUtils.LowerCaseFirstLetter(s);
174 return sb.toString();
175 }
176
177 /**
178 * return true if input method
179 * has a corresponding read method.
180 *
181 * @param m The input method
182 * @return true if read method present.
183 */
184 public boolean hasReadMethod(Method m) {
185 Method ma[] = getReadMethods();
186 String s = getPropertyName(m);
187 for (int i = 0; i < ma.length; i++) {
188 if (s.equals(getPropertyName(ma[i]))) return true;
189 }
190 return false;
191 }
192
193 public java.lang.reflect.Method[] getReadWriteMethods() {
194 java.lang.reflect.Method m[] = getMethods();
195 MethodList ml = new MethodList();
196 for (int i = 0; i < m.length; i++) {
197 String s = m[i].getName();
198 if (s.startsWith("set"))
199 if (hasReadMethod(m[i]))
200 ml.add(m[i]);
201 }
202 return ml.getMethods();
203 }
204
205 public java.lang.reflect.Method[] getWriteMethods() {
206 java.lang.reflect.Method m[] = getMethods();
207 MethodList ml = new MethodList();
208 for (int i = 0; i < m.length; i++) {
209 String s = m[i].getName();
210 if (s.startsWith("set"))
211 ml.add(m[i]);
212 }
213 return ml.getMethods();
214 }
215
216 public java.lang.reflect.Method[] getAllPublicStaticMethods() {
217 java.lang.reflect.Method m[] = getAllPublicMethods();
218 MethodList ml = new MethodList();
219 for (int i = 0; i < m.length; i++) {
220 String s = m[i].toString();
221 if (s.indexOf("static") != -1)
222 ml.add(m[i]);
223 }
224 return ml.getMethods();
225 }
226
227
228
229 public java.lang.reflect.Method[] getAllPublicMethods() {
230 java.lang.reflect.Method m[] = getMethods();
231 return getPublicMethods(m);
232 }
233 public Method[] getPublicReadMethods() {
234 return getPublicMethods(getReadMethods()) ;
235 }
236 public static Method[] getPublicMethods(Method[] m) {
237 MethodList ml = new MethodList();
238 for (int i = 0; i < m.length; i++) {
239 String s = m[i].toString();
240 if (s.startsWith("public"))
241 ml.add(m[i]);
242 }
243 return ml.getMethods();
244 }
245
246 public java.lang.reflect.Method[] getReadMethods() {
247 java.lang.reflect.Method m[] = getMethods();
248 MethodList ml = new MethodList();
249 for (int i = 0; i < m.length; i++) {
250 String s = m[i].getName();
251 if (s.startsWith("get") || s.startsWith("is"))
252 ml.add(m[i]);
253 }
254 return ml.getMethods();
255 }
256
257 public boolean containedBy(java.lang.reflect.Method m) {
258 if (index(m) == -1) return false;
259 return true;
260 }
261
262 /**
263 * turn a <code>Vector</code> of methods into an array of methods
264 */
265 private static java.lang.reflect.Method[]
266 getMethods(java.util.Vector vm) {
267 java.lang.reflect.Method ma[] =
268 new java.lang.reflect.Method[vm.size()];
269 vm.copyInto(ma);
270 return ma;
271 }
272
273 public Class[] getReturnTypes() {
274 Method m[] = getMethods();
275 Class ca[] = new Class[m.length];
276 for (int i = 0; i < m.length; i++)
277 ca[i] = m[i].getReturnType();
278 return ca;
279 }
280
281 /**
282 * return the internally held data as an array of methods;
283 */
284 public java.lang.reflect.Method[] getMethods() {
285 return getMethods(v);
286 }
287
288 /**
289 * Return all the methods in the array that
290 * are not contained in the method list.
291 */
292 public java.lang.reflect.Method[]
293 filter(java.lang.reflect.Method m[]) {
294 MethodList ml = new MethodList();
295 for (int i = 0; i < m.length; i++) {
296 java.lang.reflect.Method u = m[i];
297 if (!containedBy(u))
298 ml.add(u);
299 else
300 System.out.println("// removed:" + u);
301 }
302 return ml.getMethods();
303 }
304
305 /**
306 * get number of methods in list
307 */
308 public int size() {
309 return v.size();
310 }
311
312 public java.lang.reflect.Method elementAt(int i) {
313 return (java.lang.reflect.Method) v.elementAt(i);
314 }
315
316 public void add(java.lang.reflect.Method m) {
317 v.addElement(m);
318 }
319
320 public void add(java.lang.reflect.Method m[]) {
321 for (int i = 0; i < m.length; i++)
322 v.addElement(m[i]);
323 }
324
325 /**
326 * determine if two methods are equal.
327 * If they are non-null, have the same names
328 * and parameter lists, then they are equal.
329 */
330 public static boolean equals(java.lang.reflect.Method m1,
331 java.lang.reflect.Method m2) {
332 if (m1 == null)
333 return false;
334 if (m2 == null)
335 return false;
336 if (!m1.getName().equals(m2.getName()))
337 return false;
338 Class[] p1 = m1.getParameterTypes();
339 Class[] p2 = m2.getParameterTypes();
340 if (p1.length != p2.length)
341 return false;
342 for (int i = 0; i < p1.length; i++)
343 if (p1[i] != p2[i])
344 return false;
345 return true;
346 }
347
348 public static boolean hasPublicTransientProperty(Class c, Method m) {
349 try {
350 System.out.println("checking:" + m.getName());
351 String name = getPropertyName(m);
352 System.out.println("prop:" + name);
353 // only returns public fields!
354 Field f = c.getField(name);
355 boolean aTransient = Modifier.isTransient(f.getModifiers());
356 System.out.println("isTransient=" + aTransient);
357 return aTransient;
358 } catch (NoSuchFieldException e) {
359 return false;
360 }
361 }
362
363 public static boolean hasPasswordProperty(Method m) {
364 String name = getPropertyName(m);
365 return name.endsWith("password");
366 }
367 }