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
198 pw.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
199
200
201 if (c.getSuperclass() != null)
202 pw.print(" extends " + c.getSuperclass().getName());
203
204
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
347 pw.print(" " + Modifier.toString(fields[i].getModifiers()) +
348 " " + getTypeName(fields[i].getType()) +
349 " " + fields[i].getName());
350
351
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 }