View Javadoc

1   /***
2    *  The contents of this file are subject to the Mozilla Public
3    *  License Version 1.1 (the "License"); you may not use this file
4    *  except in compliance with the License. You may obtain a copy of
5    *  the License at http://www.mozilla.org/MPL/
6    *
7    *  Software distributed under the License is distributed on an "AS
8    *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9    *  implied. See the License for the specific language governing
10   *  rights and limitations under the License.
11   *
12   *  The Original Code is pow2toolkit library.
13   *
14   *  The Initial Owner of the Original Code is
15   *  Power Of Two S.R.L. (www.pow2.com)
16   *
17   *  Portions created by Power Of Two S.R.L. are
18   *  Copyright (C) Power Of Two S.R.L.
19   *  All Rights Reserved.
20   *
21   * Contributor(s):
22   */
23  package com.pow2.util;
24  
25  
26  import java.io.*;
27  import java.lang.reflect.*;
28  
29  import org.apache.log4j.Category;
30  
31  
32  /***
33   *  Reflection Utility class.
34   */
35  public class ReflectionUtil
36  {
37    private final static Category cat = Category.getInstance(ReflectionUtil.class);
38  
39  
40    /***
41     * Return the object having the input class name, instanced with the
42     * constructor having the <code>constructorArgsTypes</code> arguments.
43     *
44     * @param className              the object class name
45     * @param constructorArgsTypes   the object constructor arguments classes
46     * @param constructorArgs        the object constructor arguments values
47     * @return                       the instanced object
48     * @exception Exception if any error occurs
49     */
50    public static Object instanceObject(String   className,
51                                        Class[]  constructorArgsTypes,
52                                        Object[] constructorArgs)
53      throws Exception
54    {
55      Class       myClass        = Class.forName(className);
56      Constructor myConstructor  = myClass.getConstructor(constructorArgsTypes);
57      return myConstructor.newInstance(constructorArgs);
58    }
59  
60  
61    /***
62     *  Get the String representation of the input object
63     *
64     * @param o  the object to introspect
65     * @return   the String representation of the input object
66     */
67    public static String toString(Object o)
68    {
69      StringWriter   sw = new StringWriter();
70      BufferedWriter bw = new BufferedWriter(new PrintWriter(sw));
71      String         s  = null;
72  
73      reflectObject(o, bw);
74      s = sw.getBuffer().toString();
75  
76      try
77      {
78        sw.close();
79      }
80      catch(Exception e)
81      {
82        cat.error("::toString - cannot close the writer object", e);
83      }
84  
85      return s;
86    }
87  
88  
89    /***
90     *  Get the String representation of the class having
91     *  the input full qualified name.
92     *
93     * @param c  the full qualified name of the class to introspect
94     * @return   the String representation of the input object
95     */
96    public static String toString(String c)
97    {
98      StringWriter   sw = new StringWriter();
99      BufferedWriter bw = new BufferedWriter(new PrintWriter(sw));
100     String         s  = null;
101 
102     reflectClass(c, bw);
103     s = sw.getBuffer().toString();
104 
105     try
106     {
107       sw.close();
108     }
109     catch(Exception e)
110     {
111       cat.error("::toString - cannot close the writer object", e);
112     }
113 
114     return s;
115   }
116 
117 
118   /***
119    *  Reflect the input object state.
120    *
121    * @param  name Description of the Parameter
122    * @param  w Description of the Parameter
123    */
124   public static void reflectObject(Object o, OutputStream os)
125   {
126     Writer w = new BufferedWriter(new OutputStreamWriter(os));
127     reflectClass(o, true, w);
128   }
129 
130 
131   /***
132    *  Reflect the input object state.
133    *
134    * @param  name Description of the Parameter
135    * @param  w Description of the Parameter
136    */
137   public static void reflectObject(Object o, Writer w)
138   {
139     reflectClass(o, true, w);
140   }
141 
142 
143   /***
144    *  Reflect the input class state.
145    *
146    * @param  name Description of the Parameter
147    * @param  os Description of the Parameter
148    */
149   public static void reflectClass(String name, OutputStream os)
150   {
151     Writer w = new BufferedWriter(new OutputStreamWriter(os));
152     reflectClass(name, w);
153   }
154 
155 
156   /***
157    *  Reflect the input class state.
158    *
159    * @param  name Description of the Parameter
160    * @param  w Description of the Parameter
161    */
162   public static void reflectClass(String name, Writer w)
163   {
164     Class c = null;
165 
166     try
167     {
168       c = Class.forName(name);
169       reflectClass(c.newInstance(), false, w);
170     }
171     catch(Exception e)
172     {
173       cat.error("Class " + name + " is not found.");
174       return;
175     }
176   }
177 
178 
179 
180 
181   /***
182    *   PRIVATE methods here
183    */
184 
185 
186   /***
187    *  Reflect the input class state.
188    *
189    * @param  name Description of the Parameter
190    * @param  w Description of the Parameter
191    */
192   private static void reflectClass(Object o, boolean dumpValues, Writer w)
193   {
194     PrintWriter pw = new PrintWriter(w);
195     Class       c  = o.getClass();
196 
197     // Print Declaration
198     pw.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
199 
200     // Print Superclass
201     if (c.getSuperclass() != null)
202       pw.print("  extends " + c.getSuperclass().getName());
203 
204     // Print interfaces
205     Class interfaces[] = c.getInterfaces();
206 
207     for (int i = 0; i < interfaces.length; i++)
208     {
209       if (i == 0)
210         pw.print(" implements ");
211       else
212         pw.print(", ");
213 
214       pw.print(interfaces[i].getName());
215     }
216 
217     pw.println("\n{");
218 
219     try
220     {
221       listClassVariables(pw, o, dumpValues);
222     }
223     catch(Exception e)
224     {
225       cat.error("::reflectClass - cannot list the class variables", e);
226     }
227 
228     listClassConstructors(pw, c);
229     listClassMethods     (pw, c);
230 
231     pw.println("\n}");
232     pw.flush();
233   }
234 
235 
236   /***
237    *  Gets the typeName attribute of the Freud class
238    *
239    * @param  c Description of the Parameter
240    * @return  The typeName value
241    */
242   private static String getTypeName(Class c)
243   {
244     if (c.isArray())
245       try
246       {
247         Class cl = c;
248         int dimensions = 0;
249 
250         while (cl.isArray())
251         {
252           dimensions++;
253           cl = cl.getComponentType();
254         }
255 
256         StringBuffer sb = new StringBuffer();
257 
258         sb.append(cl.getName());
259         for (int i = 0; i < dimensions; i++)
260           sb.append("[]");
261 
262         return sb.toString();
263       }
264       catch (Throwable e)
265       {
266         cat.error("::getTypeName - cannot get the class type", e);
267       }
268 
269     return c.getName();
270   }
271 
272 
273   /***
274    *  Get the class constructors.
275    *
276    * @param  pw Description of the Parameter
277    * @param  c Description of the Parameter
278    */
279   private static void listClassConstructors(PrintWriter pw, Class c)
280   {
281     String      name           = c.getName();
282     Constructor constructors[] = c.getDeclaredConstructors();
283 
284     for (int i = 0; i < constructors.length; i++)
285     {
286       if (i == 0)
287         pw.println("  // Constructors");
288 
289       pw.print("  " + Modifier.toString(constructors[i].getModifiers()) +
290                 " " + constructors[i].getName() + "(");
291 
292       listParameters(pw, constructors[i].getParameterTypes());
293       pw.println(");");
294     }
295 
296     if (constructors.length > 0)
297       pw.println();
298   }
299 
300 
301   /***
302    *  Get the class methods
303    *
304    * @param  pw Description of the Parameter
305    * @param  c Description of the Parameter
306    */
307   private static void listClassMethods(PrintWriter pw, Class c)
308   {
309     String name      = c.getName();
310     Method methods[] = c.getDeclaredMethods();
311 
312     for (int i = 0; i < methods.length; i++)
313     {
314       if (i == 0)
315         pw.println("  // Methods");
316 
317       pw.print("  " + Modifier.toString(methods[i].getModifiers()) +
318                 " " + getTypeName(methods[i].getReturnType()) +
319                 " " + methods[i].getName() + "(");
320 
321       listParameters(pw, methods[i].getParameterTypes());
322       pw.println(");");
323     }
324   }
325 
326 
327   /***
328    *  Get the class variables
329    *
330    * @param  pw         Description of the Parameter
331    * @param  o          Description of the Parameter
332    * @param  dumpValues Description of the Parameter
333    */
334   private static void listClassVariables(PrintWriter pw, Object o, boolean dumpValues)
335     throws Exception
336   {
337     Class  c       = o.getClass();
338     String name    = c.getName();
339     Field fields[] = c.getDeclaredFields();
340 
341     for (int i = 0; i < fields.length; i++)
342     {
343       if (i == 0)
344         pw.println("  // Variables");
345 
346       // Only take those that belong to this class
347       pw.print("  " + Modifier.toString(fields[i].getModifiers()) +
348                 " " + getTypeName(fields[i].getType()) +
349                 " " + fields[i].getName()); //+ ";");
350 
351       // try to get the field value;
352       if ((o != null) && dumpValues)
353       {
354         Field  f      = fields[i];
355         String fValue = null;
356 
357         if (f.isAccessible())
358           fValue = f.get(o).toString();
359         else
360         {
361           try
362           {
363             f.setAccessible(true);
364             fValue = f.get(o).toString();
365             f.setAccessible(false);
366           }
367           catch(Exception e)
368           {
369             fValue = "NOT ACCESSIBLE";
370           }
371         }
372 
373         pw.print(" = [ " + fValue + " ]");
374       }
375 
376       pw.println(";");
377     }
378 
379     if (fields.length > 0)
380       pw.println();
381   }
382 
383 
384   /***
385    *  Get the type of the class parameters
386    *
387    * @param  pw Description of the Parameter
388    * @param  parameters Description of the Parameter
389    */
390   private static void listParameters(PrintWriter pw, Class parameters[])
391   {
392     for (int j = 0; j < parameters.length; j++)
393     {
394       pw.print(getTypeName(parameters[j]));
395 
396       if (j < (parameters.length - 1))
397         pw.print(", ");
398     }
399   }
400 }