Source Code Cross Referenced for ClassUtils.java in  » Library » Apache-common-lang » org » apache » commons » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache common lang » org.apache.commons.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.commons.lang;
018:
019:        import java.lang.reflect.Method;
020:        import java.lang.reflect.Modifier;
021:
022:        import java.util.ArrayList;
023:        import java.util.HashMap;
024:        import java.util.Iterator;
025:        import java.util.List;
026:        import java.util.Map;
027:
028:        /**
029:         * <p>Operates on classes without using reflection.</p>
030:         *
031:         * <p>This class handles invalid <code>null</code> inputs as best it can.
032:         * Each method documents its behaviour in more detail.</p>
033:         *
034:         * @author Stephen Colebourne
035:         * @author Gary Gregory
036:         * @author Norm Deane
037:         * @author Alban Peignier
038:         * @since 2.0
039:         * @version $Id: ClassUtils.java 437554 2006-08-28 06:21:41Z bayard $
040:         */
041:        public class ClassUtils {
042:
043:            /**
044:             * <p>The package separator character: <code>'&#x2e;' == {@value}</code>.</p>
045:             */
046:            public static final char PACKAGE_SEPARATOR_CHAR = '.';
047:
048:            /**
049:             * <p>The package separator String: <code>"&#x2e;"</code>.</p>
050:             */
051:            public static final String PACKAGE_SEPARATOR = String
052:                    .valueOf(PACKAGE_SEPARATOR_CHAR);
053:
054:            /**
055:             * <p>The inner class separator character: <code>'$' == {@value}</code>.</p>
056:             */
057:            public static final char INNER_CLASS_SEPARATOR_CHAR = '$';
058:
059:            /**
060:             * <p>The inner class separator String: <code>"$"</code>.</p>
061:             */
062:            public static final String INNER_CLASS_SEPARATOR = String
063:                    .valueOf(INNER_CLASS_SEPARATOR_CHAR);
064:
065:            /**
066:             * Maps primitive <code>Class</code>es to their corresponding wrapper <code>Class</code>.
067:             */
068:            private static Map primitiveWrapperMap = new HashMap();
069:            static {
070:                primitiveWrapperMap.put(Boolean.TYPE, Boolean.class);
071:                primitiveWrapperMap.put(Byte.TYPE, Byte.class);
072:                primitiveWrapperMap.put(Character.TYPE, Character.class);
073:                primitiveWrapperMap.put(Short.TYPE, Short.class);
074:                primitiveWrapperMap.put(Integer.TYPE, Integer.class);
075:                primitiveWrapperMap.put(Long.TYPE, Long.class);
076:                primitiveWrapperMap.put(Double.TYPE, Double.class);
077:                primitiveWrapperMap.put(Float.TYPE, Float.class);
078:                primitiveWrapperMap.put(Void.TYPE, Void.TYPE);
079:            }
080:
081:            /**
082:             * Maps a primitive class name to its corresponding abbreviation used in array class names.
083:             */
084:            private static Map abbreviationMap = new HashMap();
085:            static {
086:                abbreviationMap.put("int", "I");
087:                abbreviationMap.put("boolean", "Z");
088:                abbreviationMap.put("float", "F");
089:                abbreviationMap.put("long", "J");
090:                abbreviationMap.put("short", "S");
091:                abbreviationMap.put("byte", "B");
092:                abbreviationMap.put("double", "D");
093:                abbreviationMap.put("char", "C");
094:            }
095:
096:            /**
097:             * <p>ClassUtils instances should NOT be constructed in standard programming.
098:             * Instead, the class should be used as
099:             * <code>ClassUtils.getShortClassName(cls)</code>.</p>
100:             *
101:             * <p>This constructor is public to permit tools that require a JavaBean
102:             * instance to operate.</p>
103:             */
104:            public ClassUtils() {
105:                super ();
106:            }
107:
108:            // Short class name
109:            // ----------------------------------------------------------------------
110:            /**
111:             * <p>Gets the class name minus the package name for an <code>Object</code>.</p>
112:             *
113:             * @param object  the class to get the short name for, may be null
114:             * @param valueIfNull  the value to return if null
115:             * @return the class name of the object without the package name, or the null value
116:             */
117:            public static String getShortClassName(Object object,
118:                    String valueIfNull) {
119:                if (object == null) {
120:                    return valueIfNull;
121:                }
122:                return getShortClassName(object.getClass().getName());
123:            }
124:
125:            /**
126:             * <p>Gets the class name minus the package name from a <code>Class</code>.</p>
127:             *
128:             * @param cls  the class to get the short name for.
129:             * @return the class name without the package name or an empty string
130:             */
131:            public static String getShortClassName(Class cls) {
132:                if (cls == null) {
133:                    return StringUtils.EMPTY;
134:                }
135:                return getShortClassName(cls.getName());
136:            }
137:
138:            /**
139:             * <p>Gets the class name minus the package name from a String.</p>
140:             *
141:             * <p>The string passed in is assumed to be a class name - it is not checked.</p>
142:             *
143:             * @param className  the className to get the short name for
144:             * @return the class name of the class without the package name or an empty string
145:             */
146:            public static String getShortClassName(String className) {
147:                if (className == null) {
148:                    return StringUtils.EMPTY;
149:                }
150:                if (className.length() == 0) {
151:                    return StringUtils.EMPTY;
152:                }
153:                char[] chars = className.toCharArray();
154:                int lastDot = 0;
155:                for (int i = 0; i < chars.length; i++) {
156:                    if (chars[i] == PACKAGE_SEPARATOR_CHAR) {
157:                        lastDot = i + 1;
158:                    } else if (chars[i] == INNER_CLASS_SEPARATOR_CHAR) { // handle inner classes
159:                        chars[i] = PACKAGE_SEPARATOR_CHAR;
160:                    }
161:                }
162:                return new String(chars, lastDot, chars.length - lastDot);
163:            }
164:
165:            // Package name
166:            // ----------------------------------------------------------------------
167:            /**
168:             * <p>Gets the package name of an <code>Object</code>.</p>
169:             *
170:             * @param object  the class to get the package name for, may be null
171:             * @param valueIfNull  the value to return if null
172:             * @return the package name of the object, or the null value
173:             */
174:            public static String getPackageName(Object object,
175:                    String valueIfNull) {
176:                if (object == null) {
177:                    return valueIfNull;
178:                }
179:                return getPackageName(object.getClass().getName());
180:            }
181:
182:            /**
183:             * <p>Gets the package name of a <code>Class</code>.</p>
184:             *
185:             * @param cls  the class to get the package name for, may be <code>null</code>.
186:             * @return the package name or an empty string
187:             */
188:            public static String getPackageName(Class cls) {
189:                if (cls == null) {
190:                    return StringUtils.EMPTY;
191:                }
192:                return getPackageName(cls.getName());
193:            }
194:
195:            /**
196:             * <p>Gets the package name from a <code>String</code>.</p>
197:             *
198:             * <p>The string passed in is assumed to be a class name - it is not checked.</p>
199:             * <p>If the class is unpackaged, return an empty string.</p>
200:             *
201:             * @param className  the className to get the package name for, may be <code>null</code>
202:             * @return the package name or an empty string
203:             */
204:            public static String getPackageName(String className) {
205:                if (className == null) {
206:                    return StringUtils.EMPTY;
207:                }
208:                int i = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR);
209:                if (i == -1) {
210:                    return StringUtils.EMPTY;
211:                }
212:                return className.substring(0, i);
213:            }
214:
215:            // Superclasses/Superinterfaces
216:            // ----------------------------------------------------------------------
217:            /**
218:             * <p>Gets a <code>List</code> of superclasses for the given class.</p>
219:             *
220:             * @param cls  the class to look up, may be <code>null</code>
221:             * @return the <code>List</code> of superclasses in order going up from this one
222:             *  <code>null</code> if null input
223:             */
224:            public static List getAllSuperclasses(Class cls) {
225:                if (cls == null) {
226:                    return null;
227:                }
228:                List classes = new ArrayList();
229:                Class super class = cls.getSuperclass();
230:                while (super class != null) {
231:                    classes.add(super class);
232:                    super class = super class.getSuperclass();
233:                }
234:                return classes;
235:            }
236:
237:            /**
238:             * <p>Gets a <code>List</code> of all interfaces implemented by the given
239:             * class and its superclasses.</p>
240:             *
241:             * <p>The order is determined by looking through each interface in turn as
242:             * declared in the source file and following its hierarchy up. Then each
243:             * superclass is considered in the same way. Later duplicates are ignored,
244:             * so the order is maintained.</p>
245:             *
246:             * @param cls  the class to look up, may be <code>null</code>
247:             * @return the <code>List</code> of interfaces in order,
248:             *  <code>null</code> if null input
249:             */
250:            public static List getAllInterfaces(Class cls) {
251:                if (cls == null) {
252:                    return null;
253:                }
254:                List list = new ArrayList();
255:                while (cls != null) {
256:                    Class[] interfaces = cls.getInterfaces();
257:                    for (int i = 0; i < interfaces.length; i++) {
258:                        if (list.contains(interfaces[i]) == false) {
259:                            list.add(interfaces[i]);
260:                        }
261:                        List super Interfaces = getAllInterfaces(interfaces[i]);
262:                        for (Iterator it = super Interfaces.iterator(); it
263:                                .hasNext();) {
264:                            Class intface = (Class) it.next();
265:                            if (list.contains(intface) == false) {
266:                                list.add(intface);
267:                            }
268:                        }
269:                    }
270:                    cls = cls.getSuperclass();
271:                }
272:                return list;
273:            }
274:
275:            // Convert list
276:            // ----------------------------------------------------------------------
277:            /**
278:             * <p>Given a <code>List</code> of class names, this method converts them into classes.</p>
279:             *
280:             * <p>A new <code>List</code> is returned. If the class name cannot be found, <code>null</code>
281:             * is stored in the <code>List</code>. If the class name in the <code>List</code> is
282:             * <code>null</code>, <code>null</code> is stored in the output <code>List</code>.</p>
283:             *
284:             * @param classNames  the classNames to change
285:             * @return a <code>List</code> of Class objects corresponding to the class names,
286:             *  <code>null</code> if null input
287:             * @throws ClassCastException if classNames contains a non String entry
288:             */
289:            public static List convertClassNamesToClasses(List classNames) {
290:                if (classNames == null) {
291:                    return null;
292:                }
293:                List classes = new ArrayList(classNames.size());
294:                for (Iterator it = classNames.iterator(); it.hasNext();) {
295:                    String className = (String) it.next();
296:                    try {
297:                        classes.add(Class.forName(className));
298:                    } catch (Exception ex) {
299:                        classes.add(null);
300:                    }
301:                }
302:                return classes;
303:            }
304:
305:            /**
306:             * <p>Given a <code>List</code> of <code>Class</code> objects, this method converts
307:             * them into class names.</p>
308:             *
309:             * <p>A new <code>List</code> is returned. <code>null</code> objects will be copied into
310:             * the returned list as <code>null</code>.</p>
311:             *
312:             * @param classes  the classes to change
313:             * @return a <code>List</code> of class names corresponding to the Class objects,
314:             *  <code>null</code> if null input
315:             * @throws ClassCastException if <code>classes</code> contains a non-<code>Class</code> entry
316:             */
317:            public static List convertClassesToClassNames(List classes) {
318:                if (classes == null) {
319:                    return null;
320:                }
321:                List classNames = new ArrayList(classes.size());
322:                for (Iterator it = classes.iterator(); it.hasNext();) {
323:                    Class cls = (Class) it.next();
324:                    if (cls == null) {
325:                        classNames.add(null);
326:                    } else {
327:                        classNames.add(cls.getName());
328:                    }
329:                }
330:                return classNames;
331:            }
332:
333:            // Is assignable
334:            // ----------------------------------------------------------------------
335:            /**
336:             * <p>Checks if an array of Classes can be assigned to another array of Classes.</p>
337:             *
338:             * <p>This method calls {@link #isAssignable(Class, Class) isAssignable} for each
339:             * Class pair in the input arrays. It can be used to check if a set of arguments
340:             * (the first parameter) are suitably compatible with a set of method parameter types
341:             * (the second parameter).</p>
342:             *
343:             * <p>Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this
344:             * method takes into account widenings of primitive classes and
345:             * <code>null</code>s.</p>
346:             *
347:             * <p>Primitive widenings allow an int to be assigned to a <code>long</code>,
348:             * <code>float</code> or <code>double</code>. This method returns the correct
349:             * result for these cases.</p>
350:             *
351:             * <p><code>Null</code> may be assigned to any reference type. This method will
352:             * return <code>true</code> if <code>null</code> is passed in and the toClass is
353:             * non-primitive.</p>
354:             *
355:             * <p>Specifically, this method tests whether the type represented by the
356:             * specified <code>Class</code> parameter can be converted to the type
357:             * represented by this <code>Class</code> object via an identity conversion
358:             * widening primitive or widening reference conversion. See
359:             * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language Specification</a></em>,
360:             * sections 5.1.1, 5.1.2 and 5.1.4 for details.</p>
361:             *
362:             * @param classArray  the array of Classes to check, may be <code>null</code>
363:             * @param toClassArray  the array of Classes to try to assign into, may be <code>null</code>
364:             * @return <code>true</code> if assignment possible
365:             */
366:            public static boolean isAssignable(Class[] classArray,
367:                    Class[] toClassArray) {
368:                if (ArrayUtils.isSameLength(classArray, toClassArray) == false) {
369:                    return false;
370:                }
371:                if (classArray == null) {
372:                    classArray = ArrayUtils.EMPTY_CLASS_ARRAY;
373:                }
374:                if (toClassArray == null) {
375:                    toClassArray = ArrayUtils.EMPTY_CLASS_ARRAY;
376:                }
377:                for (int i = 0; i < classArray.length; i++) {
378:                    if (isAssignable(classArray[i], toClassArray[i]) == false) {
379:                        return false;
380:                    }
381:                }
382:                return true;
383:            }
384:
385:            /**
386:             * <p>Checks if one <code>Class</code> can be assigned to a variable of
387:             * another <code>Class</code>.</p>
388:             *
389:             * <p>Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method,
390:             * this method takes into account widenings of primitive classes and
391:             * <code>null</code>s.</p>
392:             *
393:             * <p>Primitive widenings allow an int to be assigned to a long, float or
394:             * double. This method returns the correct result for these cases.</p>
395:             *
396:             * <p><code>Null</code> may be assigned to any reference type. This method
397:             * will return <code>true</code> if <code>null</code> is passed in and the
398:             * toClass is non-primitive.</p>
399:             *
400:             * <p>Specifically, this method tests whether the type represented by the
401:             * specified <code>Class</code> parameter can be converted to the type
402:             * represented by this <code>Class</code> object via an identity conversion
403:             * widening primitive or widening reference conversion. See
404:             * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language Specification</a></em>,
405:             * sections 5.1.1, 5.1.2 and 5.1.4 for details.</p>
406:             *
407:             * @param cls  the Class to check, may be null
408:             * @param toClass  the Class to try to assign into, returns false if null
409:             * @return <code>true</code> if assignment possible
410:             */
411:            public static boolean isAssignable(Class cls, Class toClass) {
412:                if (toClass == null) {
413:                    return false;
414:                }
415:                // have to check for null, as isAssignableFrom doesn't
416:                if (cls == null) {
417:                    return !(toClass.isPrimitive());
418:                }
419:                if (cls.equals(toClass)) {
420:                    return true;
421:                }
422:                if (cls.isPrimitive()) {
423:                    if (toClass.isPrimitive() == false) {
424:                        return false;
425:                    }
426:                    if (Integer.TYPE.equals(cls)) {
427:                        return Long.TYPE.equals(toClass)
428:                                || Float.TYPE.equals(toClass)
429:                                || Double.TYPE.equals(toClass);
430:                    }
431:                    if (Long.TYPE.equals(cls)) {
432:                        return Float.TYPE.equals(toClass)
433:                                || Double.TYPE.equals(toClass);
434:                    }
435:                    if (Boolean.TYPE.equals(cls)) {
436:                        return false;
437:                    }
438:                    if (Double.TYPE.equals(cls)) {
439:                        return false;
440:                    }
441:                    if (Float.TYPE.equals(cls)) {
442:                        return Double.TYPE.equals(toClass);
443:                    }
444:                    if (Character.TYPE.equals(cls)) {
445:                        return Integer.TYPE.equals(toClass)
446:                                || Long.TYPE.equals(toClass)
447:                                || Float.TYPE.equals(toClass)
448:                                || Double.TYPE.equals(toClass);
449:                    }
450:                    if (Short.TYPE.equals(cls)) {
451:                        return Integer.TYPE.equals(toClass)
452:                                || Long.TYPE.equals(toClass)
453:                                || Float.TYPE.equals(toClass)
454:                                || Double.TYPE.equals(toClass);
455:                    }
456:                    if (Byte.TYPE.equals(cls)) {
457:                        return Short.TYPE.equals(toClass)
458:                                || Integer.TYPE.equals(toClass)
459:                                || Long.TYPE.equals(toClass)
460:                                || Float.TYPE.equals(toClass)
461:                                || Double.TYPE.equals(toClass);
462:                    }
463:                    // should never get here
464:                    return false;
465:                }
466:                return toClass.isAssignableFrom(cls);
467:            }
468:
469:            /**
470:             * <p>Converts the specified primitive Class object to its corresponding
471:             * wrapper Class object.</p>
472:             *
473:             * <p>NOTE: From v2.2, this method handles <code>Void.TYPE</code>,
474:             * returning <code>Void.TYPE</code>.</p>
475:             *
476:             * @param cls  the class to convert, may be null
477:             * @return the wrapper class for <code>cls</code> or <code>cls</code> if
478:             * <code>cls</code> is not a primitive. <code>null</code> if null input.
479:             * @since 2.1
480:             */
481:            public static Class primitiveToWrapper(Class cls) {
482:                Class convertedClass = cls;
483:                if (cls != null && cls.isPrimitive()) {
484:                    convertedClass = (Class) primitiveWrapperMap.get(cls);
485:                }
486:                return convertedClass;
487:            }
488:
489:            /**
490:             * <p>Converts the specified array of primitive Class objects to an array of
491:             * its corresponding wrapper Class objects.</p>
492:             *
493:             * @param classes  the class array to convert, may be null or empty
494:             * @return an array which contains for each given class, the wrapper class or
495:             * the original class if class is not a primitive. <code>null</code> if null input.
496:             * Empty array if an empty array passed in.
497:             * @since 2.1
498:             */
499:            public static Class[] primitivesToWrappers(Class[] classes) {
500:                if (classes == null) {
501:                    return null;
502:                }
503:
504:                if (classes.length == 0) {
505:                    return classes;
506:                }
507:
508:                Class[] convertedClasses = new Class[classes.length];
509:                for (int i = 0; i < classes.length; i++) {
510:                    convertedClasses[i] = primitiveToWrapper(classes[i]);
511:                }
512:                return convertedClasses;
513:            }
514:
515:            // Inner class
516:            // ----------------------------------------------------------------------
517:            /**
518:             * <p>Is the specified class an inner class or static nested class.</p>
519:             *
520:             * @param cls  the class to check, may be null
521:             * @return <code>true</code> if the class is an inner or static nested class,
522:             *  false if not or <code>null</code>
523:             */
524:            public static boolean isInnerClass(Class cls) {
525:                if (cls == null) {
526:                    return false;
527:                }
528:                return cls.getName().indexOf(INNER_CLASS_SEPARATOR_CHAR) >= 0;
529:            }
530:
531:            // Class loading
532:            // ----------------------------------------------------------------------
533:            /**
534:             * Returns the class represented by <code>className</code> using the
535:             * <code>classLoader</code>.  This implementation supports names like
536:             * "<code>java.lang.String[]</code>" as well as "<code>[Ljava.lang.String;</code>".
537:             *
538:             * @param classLoader  the class loader to use to load the class
539:             * @param className  the class name
540:             * @param initialize  whether the class must be initialized
541:             * @return the class represented by <code>className</code> using the <code>classLoader</code>
542:             * @throws ClassNotFoundException if the class is not found
543:             */
544:            public static Class getClass(ClassLoader classLoader,
545:                    String className, boolean initialize)
546:                    throws ClassNotFoundException {
547:                Class clazz;
548:                if (abbreviationMap.containsKey(className)) {
549:                    String clsName = "[" + abbreviationMap.get(className);
550:                    clazz = Class.forName(clsName, initialize, classLoader)
551:                            .getComponentType();
552:                } else {
553:                    clazz = Class.forName(toProperClassName(className),
554:                            initialize, classLoader);
555:                }
556:                return clazz;
557:            }
558:
559:            /**
560:             * Returns the (initialized) class represented by <code>className</code>
561:             * using the <code>classLoader</code>.  This implementation supports names
562:             * like "<code>java.lang.String[]</code>" as well as
563:             * "<code>[Ljava.lang.String;</code>".
564:             *
565:             * @param classLoader  the class loader to use to load the class
566:             * @param className  the class name
567:             * @return the class represented by <code>className</code> using the <code>classLoader</code>
568:             * @throws ClassNotFoundException if the class is not found
569:             */
570:            public static Class getClass(ClassLoader classLoader,
571:                    String className) throws ClassNotFoundException {
572:                return getClass(classLoader, className, true);
573:            }
574:
575:            /**
576:             * Returns the (initialized )class represented by <code>className</code>
577:             * using the current thread's context class loader. This implementation
578:             * supports names like "<code>java.lang.String[]</code>" as well as
579:             * "<code>[Ljava.lang.String;</code>".
580:             *
581:             * @param className  the class name
582:             * @return the class represented by <code>className</code> using the current thread's context class loader
583:             * @throws ClassNotFoundException if the class is not found
584:             */
585:            public static Class getClass(String className)
586:                    throws ClassNotFoundException {
587:                return getClass(className, true);
588:            }
589:
590:            /**
591:             * Returns the class represented by <code>className</code> using the
592:             * current thread's context class loader. This implementation supports
593:             * names like "<code>java.lang.String[]</code>" as well as
594:             * "<code>[Ljava.lang.String;</code>".
595:             *
596:             * @param className  the class name
597:             * @param initialize  whether the class must be initialized
598:             * @return the class represented by <code>className</code> using the current thread's context class loader
599:             * @throws ClassNotFoundException if the class is not found
600:             */
601:            public static Class getClass(String className, boolean initialize)
602:                    throws ClassNotFoundException {
603:                ClassLoader contextCL = Thread.currentThread()
604:                        .getContextClassLoader();
605:                ClassLoader loader = contextCL == null ? ClassUtils.class
606:                        .getClassLoader() : contextCL;
607:                return getClass(loader, className, initialize);
608:            }
609:
610:            // Public method
611:            // ----------------------------------------------------------------------
612:            /**
613:             * <p>Returns the desired Method much like <code>Class.getMethod</code>, however 
614:             * it ensures that the returned Method is from a public class or interface and not 
615:             * from an anonymous inner class. This means that the Method is invokable and 
616:             * doesn't fall foul of Java bug 
617:             * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957">4071957</a>).
618:             *
619:             *  <code><pre>Set set = Collections.unmodifiableSet(...);
620:             *  Method method = ClassUtils.getPublicMethod(set.getClass(), "isEmpty",  new Class[0]);
621:             *  Object result = method.invoke(set, new Object[]);</pre></code>
622:             * </p>
623:             *
624:             * @param cls  the class to check, not null
625:             * @param methodName  the name of the method
626:             * @param parameterTypes  the list of parameters
627:             * @return the method
628:             * @throws NullPointerException if the class is null
629:             * @throws SecurityException if a a security violation occured
630:             * @throws NoSuchMethodException if the method is not found in the given class
631:             *  or if the metothod doen't conform with the requirements
632:             */
633:            public static Method getPublicMethod(Class cls, String methodName,
634:                    Class parameterTypes[]) throws SecurityException,
635:                    NoSuchMethodException {
636:
637:                Method declaredMethod = cls.getMethod(methodName,
638:                        parameterTypes);
639:                if (Modifier.isPublic(declaredMethod.getDeclaringClass()
640:                        .getModifiers())) {
641:                    return declaredMethod;
642:                }
643:
644:                List candidateClasses = new ArrayList();
645:                candidateClasses.addAll(getAllInterfaces(cls));
646:                candidateClasses.addAll(getAllSuperclasses(cls));
647:
648:                for (Iterator it = candidateClasses.iterator(); it.hasNext();) {
649:                    Class candidateClass = (Class) it.next();
650:                    if (!Modifier.isPublic(candidateClass.getModifiers())) {
651:                        continue;
652:                    }
653:                    Method candidateMethod;
654:                    try {
655:                        candidateMethod = candidateClass.getMethod(methodName,
656:                                parameterTypes);
657:                    } catch (NoSuchMethodException ex) {
658:                        continue;
659:                    }
660:                    if (Modifier.isPublic(candidateMethod.getDeclaringClass()
661:                            .getModifiers())) {
662:                        return candidateMethod;
663:                    }
664:                }
665:
666:                throw new NoSuchMethodException(
667:                        "Can't find a public method for " + methodName + " "
668:                                + ArrayUtils.toString(parameterTypes));
669:            }
670:
671:            // ----------------------------------------------------------------------
672:            /**
673:             * Converts a class name to a JLS style class name.
674:             *
675:             * @param className  the class name
676:             * @return the converted name
677:             */
678:            private static String toProperClassName(String className) {
679:                className = StringUtils.deleteWhitespace(className);
680:                if (className == null) {
681:                    throw new NullArgumentException("className");
682:                } else if (className.endsWith("[]")) {
683:                    StringBuffer classNameBuffer = new StringBuffer();
684:                    while (className.endsWith("[]")) {
685:                        className = className.substring(0,
686:                                className.length() - 2);
687:                        classNameBuffer.append("[");
688:                    }
689:                    String abbreviation = (String) abbreviationMap
690:                            .get(className);
691:                    if (abbreviation != null) {
692:                        classNameBuffer.append(abbreviation);
693:                    } else {
694:                        classNameBuffer.append("L").append(className).append(
695:                                ";");
696:                    }
697:                    className = classNameBuffer.toString();
698:                }
699:                return className;
700:            }
701:
702:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.