/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  }