KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > introspector > ClassDescriptor


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.introspector;
4
5 import jodd.util.ReflectUtil;
6
7 import java.lang.reflect.Field JavaDoc;
8 import java.lang.reflect.Method JavaDoc;
9 import java.lang.reflect.Modifier JavaDoc;
10 import java.lang.reflect.Constructor JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.List JavaDoc;
13
14 /**
15  * A descriptor class for all methods/fields/contructors of a class.
16  * Static methods/fileds are ignored.
17  * Hash table are pre-built to speed up query.
18  * <p>
19  * Descriptors are 'lazy': various internal caches are created only on request.
20  * <p>
21  * Throughout this class, public members are defined as members
22  * defined with "public" keyword and declared in a public type.
23  * Public members declared by a non-public class is considered non-public
24  * because access to it from outside is prohibited by the java access control
25  * anyway.
26  * <p>
27  * Public members defined in public classes are always prefered even
28  * when we allow private/protected members and types to be visible.
29  * So if a non-public subtype and a public super type both have a field
30  * with the same name, the field in the public super type is always used.
31  */

32 public class ClassDescriptor {
33
34     private final Class JavaDoc type;
35     private int usage;
36
37     protected ClassDescriptor(Class JavaDoc type) {
38         this.type = type;
39         usage = 1;
40         isMap = ReflectUtil.isSubclass(type, Map JavaDoc.class);
41         isList = ReflectUtil.isSubclass(type, List JavaDoc.class);
42     }
43
44     /**
45      * Get the class object that this descriptor describes.
46      */

47     public Class JavaDoc getType() {
48         return type;
49     }
50
51     /**
52      * Increases descriptor usage.
53      */

54     protected void increaseUsage() {
55         usage++;
56     }
57
58     /**
59      * Returns number of class description usages.
60      */

61     public int getUsage() {
62         return usage;
63     }
64
65     // ---------------------------------------------------------------- special
66

67     private boolean isMap;
68     /**
69      * Returns <code>true</code> if class is a Map.
70      */

71     public boolean isMap() {
72         return isMap;
73     }
74
75     private boolean isList;
76     /**
77      * Returns <code>true</code> if class is a List.
78      */

79     public boolean isList() {
80         return isList;
81     }
82
83     // ---------------------------------------------------------------- fields
84

85     protected Fields publicFields;
86     protected Fields allFields;
87
88     /**
89      * Inspect class fields and create fields cache.
90      * Default implementation uses {@link ReflectUtil#getAccessibleFields(Class)} for retrieving
91      * only accessible fields.
92      */

93     protected void inspectFields() {
94         if (allFields != null) {
95             return;
96         }
97         Fields publicFields = new Fields();
98         Fields allFields = new Fields();
99
100         Field JavaDoc[] fields = ReflectUtil.getAccessibleFields(type);
101         for (int i = 0; i < fields.length; i++) {
102             Field JavaDoc field = fields[i];
103             String JavaDoc fName = field.getName();
104             if (ReflectUtil.isPublic(field)) {
105                 publicFields.addField(fName, field);
106             }
107             ReflectUtil.forceAccess(field);
108             allFields.addField(fName, field);
109         }
110         publicFields.lock();
111         allFields.lock();
112         this.publicFields = publicFields;
113         this.allFields = allFields;
114     }
115
116     /**
117      * Returns the field identified by name or <code>null</code> if not found.
118      *
119      * @param name field name
120      * @param suppressSecurity whether to look at non-public ones.
121      */

122     public Field JavaDoc getField(String JavaDoc name, boolean suppressSecurity) {
123         inspectFields();
124         if (suppressSecurity == true) {
125             return allFields.getField(name);
126         } else {
127             return publicFields.getField(name);
128         }
129     }
130
131     /**
132      * Returns the public field identified by name or <code>null</code> if not found.
133      */

134     public Field JavaDoc getField(String JavaDoc name) {
135         inspectFields();
136         return publicFields.getField(name);
137     }
138
139     /**
140      * Returns the total number of fields.
141      */

142     public int getFieldCount(boolean suppressSecurity) {
143         inspectFields();
144         if (suppressSecurity == true) {
145             return allFields.getCount();
146         } else {
147             return publicFields.getCount();
148         }
149     }
150
151     /**
152      * Returns the total number of public fields.
153      */

154     public int getFieldCount() {
155         inspectFields();
156         return publicFields.getCount();
157     }
158
159     /**
160      * Returns an array of all fields.
161      */

162     public Field JavaDoc[] getAllFields(boolean suppressSecurity) {
163         inspectFields();
164         if (suppressSecurity == true) {
165             return allFields.getAllFields();
166         } else {
167             return publicFields.getAllFields();
168         }
169     }
170     /**
171      * Returns an array of all public fields.
172      */

173     public Field JavaDoc[] getAllFields() {
174         inspectFields();
175         return publicFields.getAllFields();
176     }
177
178
179     // ---------------------------------------------------------------- methods
180

181     protected Methods publicMethods;
182     protected Methods allMethods;
183
184
185     /**
186      * Inspect methods and create methods cache.
187      * Default implementation uses {@link ReflectUtil#getAccessibleMethods(Class)} for retrieving
188      * only accessible methods.
189      */

190     protected void inspectMethods() {
191         if (allMethods != null) {
192             return;
193         }
194         Methods publicMethods = new Methods();
195         Methods allMethods = new Methods();
196
197         Method JavaDoc[] methods = ReflectUtil.getAccessibleMethods(type);
198         for (int i = 0; i < methods.length; i++) {
199             Method JavaDoc method = methods[i];
200             String JavaDoc methodName = method.getName();
201             if (ReflectUtil.isPublic(method)) {
202                 publicMethods.addMethod(methodName, method);
203             }
204             ReflectUtil.forceAccess(method);
205             allMethods.addMethod(methodName, method);
206         }
207         allMethods.lock();
208         publicMethods.lock();
209         this.allMethods = allMethods;
210         this.publicMethods = publicMethods;
211     }
212
213     /**
214      * Returns the method identified by name or <code>null</code> if not found.
215      *
216      * @param name method name
217      * @param suppressSecurity whether to look at non-public ones.
218      */

219     public Method JavaDoc getMethod(String JavaDoc name, boolean suppressSecurity) {
220         inspectMethods();
221         if (suppressSecurity == true) {
222             return allMethods.getMethod(name);
223         } else {
224             return publicMethods.getMethod(name);
225         }
226     }
227
228     /**
229      * Returns the public method identified by name or <code>null</code> if not found.
230      */

231     public Method JavaDoc getMethod(String JavaDoc name) {
232         inspectMethods();
233         return publicMethods.getMethod(name);
234     }
235
236     /**
237      * Returns the method identified by name and parameters.
238      */

239     public Method JavaDoc getMethod(String JavaDoc name, Class JavaDoc[] params, boolean suppressSecurity) {
240         inspectMethods();
241         if (suppressSecurity == true) {
242             return allMethods.getMethod(name, params);
243         } else {
244             return publicMethods.getMethod(name, params);
245         }
246     }
247     /**
248      * Returns the public method identified by name and parameters.
249      */

250     public Method JavaDoc getMethod(String JavaDoc name, Class JavaDoc[] params) {
251         inspectMethods();
252         return publicMethods.getMethod(name, params);
253     }
254
255     /**
256      * Returns an array of all methods with the same name.
257      */

258     public Method JavaDoc[] getAllMethods(String JavaDoc name, boolean supressSecurity) {
259         inspectMethods();
260         if (supressSecurity == true) {
261             return allMethods.getAllMethods(name);
262         } else {
263             return publicMethods.getAllMethods(name);
264         }
265     }
266     /**
267      * Returns an array of all public methods with the same name.
268      */

269     public Method JavaDoc[] getAllMethods(String JavaDoc name) {
270         inspectMethods();
271         return publicMethods.getAllMethods(name);
272     }
273
274     /**
275      * Returns an array of all methods.
276      */

277     public Method JavaDoc[] getAllMethods(boolean supressSecurity) {
278         inspectMethods();
279         if (supressSecurity == true) {
280             return allMethods.getAllMethods();
281         } else {
282             return publicMethods.getAllMethods();
283         }
284     }
285
286     /**
287      * Returns an array of all public methods.
288      */

289     public Method JavaDoc[] getAllMethods() {
290         inspectMethods();
291         return publicMethods.getAllMethods();
292     }
293
294
295     // ---------------------------------------------------------------- beans
296

297     protected Properties publicProperties;
298     protected Properties allProperties;
299
300     /**
301      * Inspect methods and create properties cache.
302      */

303     protected void inspectProperties() {
304         if (publicProperties != null) {
305             return;
306         }
307         Properties publicProperties = new Properties();
308         Properties allProperties = new Properties();
309
310         Method JavaDoc[] methods = ReflectUtil.getAccessibleMethods(type);
311         for (int i = 0; i < methods.length; i++) {
312             Method JavaDoc method = methods[i];
313             if (Modifier.isStatic(method.getModifiers())) {
314                 continue; // ignore static
315
}
316             String JavaDoc methodName = method.getName();
317             Class JavaDoc[] paramTypes = method.getParameterTypes();
318             Class JavaDoc returnType = method.getReturnType();
319             boolean add = false;
320
321             if (methodName.startsWith("get") && methodName.equals("getClass") == false) { // getter method must starts with 'get' and it is not getClass()
322
if ((returnType != null) && (paramTypes.length == 0)) { // getter must have a return type and no arguments
323
methodName = '-' + methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
324                     add = true;
325                 }
326             } else if (methodName.startsWith("is")) { // ister must starts with 'is'
327
if ((returnType != null) && (paramTypes.length == 0)) { // ister must have return type and no arguments
328
methodName = '-' + methodName.substring(2, 3).toLowerCase() + methodName.substring(3);
329                     add = true;
330                 }
331             } else if (methodName.startsWith("set")) { // setter must start with a 'set'
332
if (paramTypes.length == 1) { // setter must have just one argument
333
methodName = '+' + methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
334                     add = true;
335                 }
336             }
337
338             if (add == true) {
339                 if (ReflectUtil.isPublic(method)) {
340                     publicProperties.addMethod(methodName, method);
341                 }
342                 ReflectUtil.forceAccess(method);
343                 allProperties.addMethod(methodName, method);
344             }
345         }
346         allProperties.lock();
347         publicProperties.lock();
348         this.allProperties = allProperties;
349         this.publicProperties = publicProperties;
350     }
351
352     /**
353      * Returns bean setter identified by name.
354      */

355     public Method JavaDoc getBeanSetter(String JavaDoc name, boolean suppressSecurity) {
356         inspectProperties();
357         if (suppressSecurity == true) {
358             return allProperties.setters.getMethod(name);
359         } else {
360             return publicProperties.setters.getMethod(name);
361         }
362     }
363     /**
364      * Returns public bean setter identified by name.
365      */

366     public Method JavaDoc getBeanSetter(String JavaDoc name) {
367         inspectProperties();
368         return publicProperties.setters.getMethod(name);
369     }
370     /**
371      * Returns an array of all bean setters.
372      */

373     public Method JavaDoc[] getAllBeanSetters(boolean suppressSecurity) {
374         inspectProperties();
375         if (suppressSecurity == true) {
376             return allProperties.setters.getAllMethods();
377         } else {
378             return publicProperties.setters.getAllMethods();
379         }
380     }
381     /**
382      * Returns an array of all public bean setters.
383      */

384     public Method JavaDoc[] getAllBeanSetters() {
385         inspectProperties();
386         return publicProperties.setters.getAllMethods();
387     }
388
389     /**
390      * Returns an array of all bean setters names.
391      */

392     public String JavaDoc[] getAllBeanSetterNames(boolean suppressSecurity) {
393         inspectProperties();
394         if (suppressSecurity == true) {
395             return allProperties.setterNames;
396         } else {
397             return publicProperties.setterNames;
398         }
399     }
400     /**
401      * Returns an array of all public bean setters names.
402      */

403     public String JavaDoc[] getAllBeanSetterNames() {
404         inspectProperties();
405         return publicProperties.setterNames;
406     }
407
408     /**
409      * Returns bean getter identified by name.
410      */

411     public Method JavaDoc getBeanGetter(String JavaDoc name, boolean suppressSecurity) {
412         inspectProperties();
413         if (suppressSecurity == true) {
414             return allProperties.getters.getMethod(name);
415         } else {
416             return publicProperties.getters.getMethod(name);
417         }
418     }
419
420     /**
421      * Returns public bean getter identified by name.
422      */

423     public Method JavaDoc getBeanGetter(String JavaDoc name) {
424         inspectProperties();
425         return publicProperties.getters.getMethod(name);
426     }
427     /**
428      * Returns all bean getters.
429      */

430     public Method JavaDoc[] getAllBeanGetters(boolean suppressSecurity) {
431         inspectProperties();
432         if (suppressSecurity == true) {
433             return allProperties.getters.getAllMethods();
434         } else {
435             return publicProperties.getters.getAllMethods();
436         }
437     }
438     /**
439      * Returns all public bean getters.
440      */

441     public Method JavaDoc[] getAllBeanGetters() {
442         inspectProperties();
443         return publicProperties.getters.getAllMethods();
444     }
445     /**
446      * Returns all bean getters names.
447      */

448     public String JavaDoc[] getAllBeanGetterNames(boolean suppressSecurity) {
449         inspectProperties();
450         if (suppressSecurity == true) {
451             return allProperties.getterNames;
452         } else {
453             return publicProperties.getterNames;
454         }
455     }
456     /**
457      * Returns all public bean getters names.
458      */

459     public String JavaDoc[] getAllBeanGetterNames() {
460         inspectProperties();
461         return publicProperties.getterNames;
462     }
463
464
465
466     // ---------------------------------------------------------------- ctors
467

468     protected Ctors publicCtors;
469     protected Ctors allCtors;
470
471     /**
472      * Inspect class ctors and create ctors cache.
473      * Default implementation uses {@link ReflectUtil#getAccessibleFields(Class)} for retrieving
474      * only accessible fields.
475      */

476     protected void inspectCtors() {
477         if (allCtors != null) {
478             return;
479         }
480         Ctors publicCtors = new Ctors();
481         Ctors allCtors = new Ctors();
482
483
484         publicCtors.addCtors(type.getConstructors());
485         allCtors.addCtors(type.getDeclaredConstructors());
486         Constructor JavaDoc[] ctors = allCtors.getAllCtors();
487         for (int i = 0; i < ctors.length; i++) {
488             Constructor JavaDoc ctor = ctors[i];
489             if (ReflectUtil.isPublic(ctor) == false) {
490                 ReflectUtil.forceAccess(ctor);
491             }
492         }
493         publicCtors.lock();
494         allCtors.lock();
495         this.publicCtors = publicCtors;
496         this.allCtors = allCtors;
497     }
498
499     /**
500      * Returns the default ctor or <code>null</code> if not found.
501      */

502     public Constructor JavaDoc getDefaultCtor(boolean suppressSecurity) {
503         inspectCtors();
504         if (suppressSecurity == true) {
505             return allCtors.getDefaultCtor();
506         } else {
507             return publicCtors.getDefaultCtor();
508         }
509     }
510
511     /**
512      * Returns the constructor identified by arguments or <code>null</code> if not found.
513      *
514      * @param args ctor arguments
515      * @param suppressSecurity whether to look at non-public ones.
516      */

517     public Constructor JavaDoc getCtor(Class JavaDoc[] args, boolean suppressSecurity) {
518         inspectCtors();
519         if (suppressSecurity == true) {
520             return allCtors.getCtor(args);
521         } else {
522             return publicCtors.getCtor(args);
523         }
524     }
525
526     /**
527      * Returns the public ctor identified by arguments or <code>null</code> if not found.
528      */

529     public Constructor JavaDoc getCtor(Class JavaDoc[] args) {
530         inspectCtors();
531         return publicCtors.getCtor(args);
532     }
533
534     /**
535      * Returns the public default ctor or <code>null</code> if not found.
536      */

537     public Constructor JavaDoc getDefaultCtor() {
538         inspectCtors();
539         return publicCtors.getDefaultCtor();
540     }
541
542
543
544     /**
545      * Returns the total number of constructors.
546      */

547     public int getCtorCount(boolean suppressSecurity) {
548         inspectCtors();
549         if (suppressSecurity == true) {
550             return allCtors.getCount();
551         } else {
552             return publicCtors.getCount();
553         }
554     }
555
556
557     /**
558      * Returns the total number of public constructors.
559      */

560     public int getCtorCount() {
561         inspectCtors();
562         return publicCtors.getCount();
563     }
564
565     /**
566      * Returns an array of all ctors.
567      */

568
569     public Constructor JavaDoc[] getAllCtors(boolean suppressSecurity) {
570         inspectCtors();
571         if (suppressSecurity == true) {
572             return allCtors.getAllCtors();
573         } else {
574             return publicCtors.getAllCtors();
575         }
576     }
577
578     /**
579      * Returns an array of all public ctors.
580      */

581     public Constructor JavaDoc[] getAllCtors() {
582         inspectCtors();
583         return publicCtors.getAllCtors();
584     }
585
586 }
Popular Tags