Source Code Cross Referenced for MethodUtils.java in  » Library » Apache-commons-beanutils-1.8.0-BETA-src » org » apache » commons » beanutils » 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 commons beanutils 1.8.0 BETA src » org.apache.commons.beanutils 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.commons.beanutils;
0019:
0020:        import java.lang.reflect.InvocationTargetException;
0021:        import java.lang.reflect.Method;
0022:        import java.lang.reflect.Modifier;
0023:
0024:        import java.util.WeakHashMap;
0025:
0026:        import org.apache.commons.logging.Log;
0027:        import org.apache.commons.logging.LogFactory;
0028:
0029:        /**
0030:         * <p> Utility reflection methods focussed on methods in general rather than properties in particular. </p>
0031:         *
0032:         * <h3>Known Limitations</h3>
0033:         * <h4>Accessing Public Methods In A Default Access Superclass</h4>
0034:         * <p>There is an issue when invoking public methods contained in a default access superclass.
0035:         * Reflection locates these methods fine and correctly assigns them as public.
0036:         * However, an <code>IllegalAccessException</code> is thrown if the method is invoked.</p>
0037:         *
0038:         * <p><code>MethodUtils</code> contains a workaround for this situation. 
0039:         * It will attempt to call <code>setAccessible</code> on this method.
0040:         * If this call succeeds, then the method can be invoked as normal.
0041:         * This call will only succeed when the application has sufficient security privilages. 
0042:         * If this call fails then a warning will be logged and the method may fail.</p>
0043:         *
0044:         * @author Craig R. McClanahan
0045:         * @author Ralph Schaer
0046:         * @author Chris Audley
0047:         * @author Rey Fran&#231;ois
0048:         * @author Gregor Ra&#253;man
0049:         * @author Jan Sorensen
0050:         * @author Robert Burrell Donkin
0051:         */
0052:
0053:        public class MethodUtils {
0054:
0055:            // --------------------------------------------------------- Private Methods
0056:
0057:            /** 
0058:             * Only log warning about accessibility work around once.
0059:             * <p>
0060:             * Note that this is broken when this class is deployed via a shared
0061:             * classloader in a container, as the warning message will be emitted
0062:             * only once, not once per webapp. However making the warning appear
0063:             * once per webapp means having a map keyed by context classloader
0064:             * which introduces nasty memory-leak problems. As this warning is
0065:             * really optional we can ignore this problem; only one of the webapps
0066:             * will get the warning in its logs but that should be good enough.
0067:             */
0068:            private static boolean loggedAccessibleWarning = false;
0069:
0070:            /** An empty class array */
0071:            private static final Class[] EMPTY_CLASS_PARAMETERS = new Class[0];
0072:            /** An empty object array */
0073:            private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
0074:
0075:            /**
0076:             * Stores a cache of MethodDescriptor -> Method in a WeakHashMap.
0077:             * <p>
0078:             * The keys into this map only ever exist as temporary variables within
0079:             * methods of this class, and are never exposed to users of this class.
0080:             * This means that the WeakHashMap is used only as a mechanism for 
0081:             * limiting the size of the cache, ie a way to tell the garbage collector
0082:             * that the contents of the cache can be completely garbage-collected 
0083:             * whenever it needs the memory. Whether this is a good approach to
0084:             * this problem is doubtful; something like the commons-collections
0085:             * LRUMap may be more appropriate (though of course selecting an
0086:             * appropriate size is an issue).
0087:             * <p>
0088:             * This static variable is safe even when this code is deployed via a
0089:             * shared classloader because it is keyed via a MethodDescriptor object
0090:             * which has a Class as one of its members and that member is used in
0091:             * the MethodDescriptor.equals method. So two components that load the same
0092:             * class via different classloaders will generate non-equal MethodDescriptor
0093:             * objects and hence end up with different entries in the map.
0094:             */
0095:            private static WeakHashMap cache = new WeakHashMap();
0096:
0097:            // --------------------------------------------------------- Public Methods
0098:
0099:            /**
0100:             * <p>Invoke a named method whose parameter type matches the object type.</p>
0101:             *
0102:             * <p>The behaviour of this method is less deterministic 
0103:             * than <code>invokeExactMethod()</code>.
0104:             * It loops through all methods with names that match
0105:             * and then executes the first it finds with compatable parameters.</p>
0106:             *
0107:             * <p>This method supports calls to methods taking primitive parameters 
0108:             * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
0109:             * would match a <code>boolean</code> primitive.</p>
0110:             *
0111:             * <p> This is a convenient wrapper for
0112:             * {@link #invokeMethod(Object object,String methodName,Object [] args)}.
0113:             * </p>
0114:             *
0115:             * @param object invoke method on this object
0116:             * @param methodName get method with this name
0117:             * @param arg use this argument
0118:             * @return The value returned by the invoked method
0119:             *
0120:             * @throws NoSuchMethodException if there is no such accessible method
0121:             * @throws InvocationTargetException wraps an exception thrown by the
0122:             *  method invoked
0123:             * @throws IllegalAccessException if the requested method is not accessible
0124:             *  via reflection
0125:             */
0126:            public static Object invokeMethod(Object object, String methodName,
0127:                    Object arg) throws NoSuchMethodException,
0128:                    IllegalAccessException, InvocationTargetException {
0129:
0130:                Object[] args = { arg };
0131:                return invokeMethod(object, methodName, args);
0132:
0133:            }
0134:
0135:            /**
0136:             * <p>Invoke a named method whose parameter type matches the object type.</p>
0137:             *
0138:             * <p>The behaviour of this method is less deterministic 
0139:             * than {@link #invokeExactMethod(Object object,String methodName,Object [] args)}. 
0140:             * It loops through all methods with names that match
0141:             * and then executes the first it finds with compatable parameters.</p>
0142:             *
0143:             * <p>This method supports calls to methods taking primitive parameters 
0144:             * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
0145:             * would match a <code>boolean</code> primitive.</p>
0146:             *
0147:             * <p> This is a convenient wrapper for
0148:             * {@link #invokeMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}.
0149:             * </p>
0150:             *
0151:             * @param object invoke method on this object
0152:             * @param methodName get method with this name
0153:             * @param args use these arguments - treat null as empty array
0154:             * @return The value returned by the invoked method
0155:             *
0156:             * @throws NoSuchMethodException if there is no such accessible method
0157:             * @throws InvocationTargetException wraps an exception thrown by the
0158:             *  method invoked
0159:             * @throws IllegalAccessException if the requested method is not accessible
0160:             *  via reflection
0161:             */
0162:            public static Object invokeMethod(Object object, String methodName,
0163:                    Object[] args) throws NoSuchMethodException,
0164:                    IllegalAccessException, InvocationTargetException {
0165:
0166:                if (args == null) {
0167:                    args = EMPTY_OBJECT_ARRAY;
0168:                }
0169:                int arguments = args.length;
0170:                Class[] parameterTypes = new Class[arguments];
0171:                for (int i = 0; i < arguments; i++) {
0172:                    parameterTypes[i] = args[i].getClass();
0173:                }
0174:                return invokeMethod(object, methodName, args, parameterTypes);
0175:
0176:            }
0177:
0178:            /**
0179:             * <p>Invoke a named method whose parameter type matches the object type.</p>
0180:             *
0181:             * <p>The behaviour of this method is less deterministic 
0182:             * than {@link 
0183:             * #invokeExactMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}. 
0184:             * It loops through all methods with names that match
0185:             * and then executes the first it finds with compatable parameters.</p>
0186:             *
0187:             * <p>This method supports calls to methods taking primitive parameters 
0188:             * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
0189:             * would match a <code>boolean</code> primitive.</p>
0190:             *
0191:             *
0192:             * @param object invoke method on this object
0193:             * @param methodName get method with this name
0194:             * @param args use these arguments - treat null as empty array
0195:             * @param parameterTypes match these parameters - treat null as empty array
0196:             * @return The value returned by the invoked method
0197:             *
0198:             * @throws NoSuchMethodException if there is no such accessible method
0199:             * @throws InvocationTargetException wraps an exception thrown by the
0200:             *  method invoked
0201:             * @throws IllegalAccessException if the requested method is not accessible
0202:             *  via reflection
0203:             */
0204:            public static Object invokeMethod(Object object, String methodName,
0205:                    Object[] args, Class[] parameterTypes)
0206:                    throws NoSuchMethodException, IllegalAccessException,
0207:                    InvocationTargetException {
0208:
0209:                if (parameterTypes == null) {
0210:                    parameterTypes = EMPTY_CLASS_PARAMETERS;
0211:                }
0212:                if (args == null) {
0213:                    args = EMPTY_OBJECT_ARRAY;
0214:                }
0215:
0216:                Method method = getMatchingAccessibleMethod(object.getClass(),
0217:                        methodName, parameterTypes);
0218:                if (method == null) {
0219:                    throw new NoSuchMethodException(
0220:                            "No such accessible method: " + methodName
0221:                                    + "() on object: "
0222:                                    + object.getClass().getName());
0223:                }
0224:                return method.invoke(object, args);
0225:            }
0226:
0227:            /**
0228:             * <p>Invoke a method whose parameter type matches exactly the object
0229:             * type.</p>
0230:             *
0231:             * <p> This is a convenient wrapper for
0232:             * {@link #invokeExactMethod(Object object,String methodName,Object [] args)}.
0233:             * </p>
0234:             *
0235:             * @param object invoke method on this object
0236:             * @param methodName get method with this name
0237:             * @param arg use this argument
0238:             * @return The value returned by the invoked method
0239:             *
0240:             * @throws NoSuchMethodException if there is no such accessible method
0241:             * @throws InvocationTargetException wraps an exception thrown by the
0242:             *  method invoked
0243:             * @throws IllegalAccessException if the requested method is not accessible
0244:             *  via reflection
0245:             */
0246:            public static Object invokeExactMethod(Object object,
0247:                    String methodName, Object arg)
0248:                    throws NoSuchMethodException, IllegalAccessException,
0249:                    InvocationTargetException {
0250:
0251:                Object[] args = { arg };
0252:                return invokeExactMethod(object, methodName, args);
0253:
0254:            }
0255:
0256:            /**
0257:             * <p>Invoke a method whose parameter types match exactly the object
0258:             * types.</p>
0259:             *
0260:             * <p> This uses reflection to invoke the method obtained from a call to
0261:             * <code>getAccessibleMethod()</code>.</p>
0262:             *
0263:             * @param object invoke method on this object
0264:             * @param methodName get method with this name
0265:             * @param args use these arguments - treat null as empty array
0266:             * @return The value returned by the invoked method
0267:             *
0268:             * @throws NoSuchMethodException if there is no such accessible method
0269:             * @throws InvocationTargetException wraps an exception thrown by the
0270:             *  method invoked
0271:             * @throws IllegalAccessException if the requested method is not accessible
0272:             *  via reflection
0273:             */
0274:            public static Object invokeExactMethod(Object object,
0275:                    String methodName, Object[] args)
0276:                    throws NoSuchMethodException, IllegalAccessException,
0277:                    InvocationTargetException {
0278:                if (args == null) {
0279:                    args = EMPTY_OBJECT_ARRAY;
0280:                }
0281:                int arguments = args.length;
0282:                Class[] parameterTypes = new Class[arguments];
0283:                for (int i = 0; i < arguments; i++) {
0284:                    parameterTypes[i] = args[i].getClass();
0285:                }
0286:                return invokeExactMethod(object, methodName, args,
0287:                        parameterTypes);
0288:
0289:            }
0290:
0291:            /**
0292:             * <p>Invoke a method whose parameter types match exactly the parameter
0293:             * types given.</p>
0294:             *
0295:             * <p>This uses reflection to invoke the method obtained from a call to
0296:             * <code>getAccessibleMethod()</code>.</p>
0297:             *
0298:             * @param object invoke method on this object
0299:             * @param methodName get method with this name
0300:             * @param args use these arguments - treat null as empty array
0301:             * @param parameterTypes match these parameters - treat null as empty array
0302:             * @return The value returned by the invoked method
0303:             *
0304:             * @throws NoSuchMethodException if there is no such accessible method
0305:             * @throws InvocationTargetException wraps an exception thrown by the
0306:             *  method invoked
0307:             * @throws IllegalAccessException if the requested method is not accessible
0308:             *  via reflection
0309:             */
0310:            public static Object invokeExactMethod(Object object,
0311:                    String methodName, Object[] args, Class[] parameterTypes)
0312:                    throws NoSuchMethodException, IllegalAccessException,
0313:                    InvocationTargetException {
0314:
0315:                if (args == null) {
0316:                    args = EMPTY_OBJECT_ARRAY;
0317:                }
0318:
0319:                if (parameterTypes == null) {
0320:                    parameterTypes = EMPTY_CLASS_PARAMETERS;
0321:                }
0322:
0323:                Method method = getAccessibleMethod(object.getClass(),
0324:                        methodName, parameterTypes);
0325:                if (method == null) {
0326:                    throw new NoSuchMethodException(
0327:                            "No such accessible method: " + methodName
0328:                                    + "() on object: "
0329:                                    + object.getClass().getName());
0330:                }
0331:                return method.invoke(object, args);
0332:
0333:            }
0334:
0335:            /**
0336:             * <p>Invoke a static method whose parameter types match exactly the parameter
0337:             * types given.</p>
0338:             *
0339:             * <p>This uses reflection to invoke the method obtained from a call to
0340:             * {@link #getAccessibleMethod(Class, String, Class[])}.</p>
0341:             *
0342:             * @param objectClass invoke static method on this class
0343:             * @param methodName get method with this name
0344:             * @param args use these arguments - treat null as empty array
0345:             * @param parameterTypes match these parameters - treat null as empty array
0346:             * @return The value returned by the invoked method
0347:             *
0348:             * @throws NoSuchMethodException if there is no such accessible method
0349:             * @throws InvocationTargetException wraps an exception thrown by the
0350:             *  method invoked
0351:             * @throws IllegalAccessException if the requested method is not accessible
0352:             *  via reflection
0353:             */
0354:            public static Object invokeExactStaticMethod(Class objectClass,
0355:                    String methodName, Object[] args, Class[] parameterTypes)
0356:                    throws NoSuchMethodException, IllegalAccessException,
0357:                    InvocationTargetException {
0358:
0359:                if (args == null) {
0360:                    args = EMPTY_OBJECT_ARRAY;
0361:                }
0362:
0363:                if (parameterTypes == null) {
0364:                    parameterTypes = EMPTY_CLASS_PARAMETERS;
0365:                }
0366:
0367:                Method method = getAccessibleMethod(objectClass, methodName,
0368:                        parameterTypes);
0369:                if (method == null) {
0370:                    throw new NoSuchMethodException(
0371:                            "No such accessible method: " + methodName
0372:                                    + "() on class: " + objectClass.getName());
0373:                }
0374:                return method.invoke(null, args);
0375:
0376:            }
0377:
0378:            /**
0379:             * <p>Invoke a named static method whose parameter type matches the object type.</p>
0380:             *
0381:             * <p>The behaviour of this method is less deterministic 
0382:             * than {@link #invokeExactMethod(Object, String, Object[], Class[])}. 
0383:             * It loops through all methods with names that match
0384:             * and then executes the first it finds with compatable parameters.</p>
0385:             *
0386:             * <p>This method supports calls to methods taking primitive parameters 
0387:             * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
0388:             * would match a <code>boolean</code> primitive.</p>
0389:             *
0390:             * <p> This is a convenient wrapper for
0391:             * {@link #invokeStaticMethod(Class objectClass,String methodName,Object [] args)}.
0392:             * </p>
0393:             *
0394:             * @param objectClass invoke static method on this class
0395:             * @param methodName get method with this name
0396:             * @param arg use this argument
0397:             * @return The value returned by the invoked method
0398:             *
0399:             * @throws NoSuchMethodException if there is no such accessible method
0400:             * @throws InvocationTargetException wraps an exception thrown by the
0401:             *  method invoked
0402:             * @throws IllegalAccessException if the requested method is not accessible
0403:             *  via reflection
0404:             */
0405:            public static Object invokeStaticMethod(Class objectClass,
0406:                    String methodName, Object arg)
0407:                    throws NoSuchMethodException, IllegalAccessException,
0408:                    InvocationTargetException {
0409:
0410:                Object[] args = { arg };
0411:                return invokeStaticMethod(objectClass, methodName, args);
0412:
0413:            }
0414:
0415:            /**
0416:             * <p>Invoke a named static method whose parameter type matches the object type.</p>
0417:             *
0418:             * <p>The behaviour of this method is less deterministic 
0419:             * than {@link #invokeExactMethod(Object object,String methodName,Object [] args)}. 
0420:             * It loops through all methods with names that match
0421:             * and then executes the first it finds with compatable parameters.</p>
0422:             *
0423:             * <p>This method supports calls to methods taking primitive parameters 
0424:             * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
0425:             * would match a <code>boolean</code> primitive.</p>
0426:             *
0427:             * <p> This is a convenient wrapper for
0428:             * {@link #invokeStaticMethod(Class objectClass,String methodName,Object [] args,Class[] parameterTypes)}.
0429:             * </p>
0430:             *
0431:             * @param objectClass invoke static method on this class
0432:             * @param methodName get method with this name
0433:             * @param args use these arguments - treat null as empty array
0434:             * @return The value returned by the invoked method
0435:             *
0436:             * @throws NoSuchMethodException if there is no such accessible method
0437:             * @throws InvocationTargetException wraps an exception thrown by the
0438:             *  method invoked
0439:             * @throws IllegalAccessException if the requested method is not accessible
0440:             *  via reflection
0441:             */
0442:            public static Object invokeStaticMethod(Class objectClass,
0443:                    String methodName, Object[] args)
0444:                    throws NoSuchMethodException, IllegalAccessException,
0445:                    InvocationTargetException {
0446:
0447:                if (args == null) {
0448:                    args = EMPTY_OBJECT_ARRAY;
0449:                }
0450:                int arguments = args.length;
0451:                Class[] parameterTypes = new Class[arguments];
0452:                for (int i = 0; i < arguments; i++) {
0453:                    parameterTypes[i] = args[i].getClass();
0454:                }
0455:                return invokeStaticMethod(objectClass, methodName, args,
0456:                        parameterTypes);
0457:
0458:            }
0459:
0460:            /**
0461:             * <p>Invoke a named static method whose parameter type matches the object type.</p>
0462:             *
0463:             * <p>The behaviour of this method is less deterministic 
0464:             * than {@link 
0465:             * #invokeExactStaticMethod(Class objectClass,String methodName,Object [] args,Class[] parameterTypes)}. 
0466:             * It loops through all methods with names that match
0467:             * and then executes the first it finds with compatable parameters.</p>
0468:             *
0469:             * <p>This method supports calls to methods taking primitive parameters 
0470:             * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
0471:             * would match a <code>boolean</code> primitive.</p>
0472:             *
0473:             *
0474:             * @param objectClass invoke static method on this class
0475:             * @param methodName get method with this name
0476:             * @param args use these arguments - treat null as empty array
0477:             * @param parameterTypes match these parameters - treat null as empty array
0478:             * @return The value returned by the invoked method
0479:             *
0480:             * @throws NoSuchMethodException if there is no such accessible method
0481:             * @throws InvocationTargetException wraps an exception thrown by the
0482:             *  method invoked
0483:             * @throws IllegalAccessException if the requested method is not accessible
0484:             *  via reflection
0485:             */
0486:            public static Object invokeStaticMethod(Class objectClass,
0487:                    String methodName, Object[] args, Class[] parameterTypes)
0488:                    throws NoSuchMethodException, IllegalAccessException,
0489:                    InvocationTargetException {
0490:
0491:                if (parameterTypes == null) {
0492:                    parameterTypes = EMPTY_CLASS_PARAMETERS;
0493:                }
0494:                if (args == null) {
0495:                    args = EMPTY_OBJECT_ARRAY;
0496:                }
0497:
0498:                Method method = getMatchingAccessibleMethod(objectClass,
0499:                        methodName, parameterTypes);
0500:                if (method == null) {
0501:                    throw new NoSuchMethodException(
0502:                            "No such accessible method: " + methodName
0503:                                    + "() on class: " + objectClass.getName());
0504:                }
0505:                return method.invoke(null, args);
0506:            }
0507:
0508:            /**
0509:             * <p>Invoke a static method whose parameter type matches exactly the object
0510:             * type.</p>
0511:             *
0512:             * <p> This is a convenient wrapper for
0513:             * {@link #invokeExactStaticMethod(Class objectClass,String methodName,Object [] args)}.
0514:             * </p>
0515:             *
0516:             * @param objectClass invoke static method on this class
0517:             * @param methodName get method with this name
0518:             * @param arg use this argument
0519:             * @return The value returned by the invoked method
0520:             *
0521:             * @throws NoSuchMethodException if there is no such accessible method
0522:             * @throws InvocationTargetException wraps an exception thrown by the
0523:             *  method invoked
0524:             * @throws IllegalAccessException if the requested method is not accessible
0525:             *  via reflection
0526:             */
0527:            public static Object invokeExactStaticMethod(Class objectClass,
0528:                    String methodName, Object arg)
0529:                    throws NoSuchMethodException, IllegalAccessException,
0530:                    InvocationTargetException {
0531:
0532:                Object[] args = { arg };
0533:                return invokeExactStaticMethod(objectClass, methodName, args);
0534:
0535:            }
0536:
0537:            /**
0538:             * <p>Invoke a static method whose parameter types match exactly the object
0539:             * types.</p>
0540:             *
0541:             * <p> This uses reflection to invoke the method obtained from a call to
0542:             * {@link #getAccessibleMethod(Class, String, Class[])}.</p>
0543:             *
0544:             * @param objectClass invoke static method on this class
0545:             * @param methodName get method with this name
0546:             * @param args use these arguments - treat null as empty array
0547:             * @return The value returned by the invoked method
0548:             *
0549:             * @throws NoSuchMethodException if there is no such accessible method
0550:             * @throws InvocationTargetException wraps an exception thrown by the
0551:             *  method invoked
0552:             * @throws IllegalAccessException if the requested method is not accessible
0553:             *  via reflection
0554:             */
0555:            public static Object invokeExactStaticMethod(Class objectClass,
0556:                    String methodName, Object[] args)
0557:                    throws NoSuchMethodException, IllegalAccessException,
0558:                    InvocationTargetException {
0559:                if (args == null) {
0560:                    args = EMPTY_OBJECT_ARRAY;
0561:                }
0562:                int arguments = args.length;
0563:                Class[] parameterTypes = new Class[arguments];
0564:                for (int i = 0; i < arguments; i++) {
0565:                    parameterTypes[i] = args[i].getClass();
0566:                }
0567:                return invokeExactStaticMethod(objectClass, methodName, args,
0568:                        parameterTypes);
0569:
0570:            }
0571:
0572:            /**
0573:             * <p>Return an accessible method (that is, one that can be invoked via
0574:             * reflection) with given name and a single parameter.  If no such method
0575:             * can be found, return <code>null</code>.
0576:             * Basically, a convenience wrapper that constructs a <code>Class</code>
0577:             * array for you.</p>
0578:             *
0579:             * @param clazz get method from this class
0580:             * @param methodName get method with this name
0581:             * @param parameterType taking this type of parameter
0582:             * @return The accessible method
0583:             */
0584:            public static Method getAccessibleMethod(Class clazz,
0585:                    String methodName, Class parameterType) {
0586:
0587:                Class[] parameterTypes = { parameterType };
0588:                return getAccessibleMethod(clazz, methodName, parameterTypes);
0589:
0590:            }
0591:
0592:            /**
0593:             * <p>Return an accessible method (that is, one that can be invoked via
0594:             * reflection) with given name and parameters.  If no such method
0595:             * can be found, return <code>null</code>.
0596:             * This is just a convenient wrapper for
0597:             * {@link #getAccessibleMethod(Method method)}.</p>
0598:             *
0599:             * @param clazz get method from this class
0600:             * @param methodName get method with this name
0601:             * @param parameterTypes with these parameters types
0602:             * @return The accessible method
0603:             */
0604:            public static Method getAccessibleMethod(Class clazz,
0605:                    String methodName, Class[] parameterTypes) {
0606:
0607:                try {
0608:                    MethodDescriptor md = new MethodDescriptor(clazz,
0609:                            methodName, parameterTypes, true);
0610:                    // Check the cache first
0611:                    Method method = (Method) cache.get(md);
0612:                    if (method != null) {
0613:                        return method;
0614:                    }
0615:
0616:                    method = getAccessibleMethod(clazz.getMethod(methodName,
0617:                            parameterTypes));
0618:                    cache.put(md, method);
0619:                    return method;
0620:                } catch (NoSuchMethodException e) {
0621:                    return (null);
0622:                }
0623:
0624:            }
0625:
0626:            /**
0627:             * <p>Return an accessible method (that is, one that can be invoked via
0628:             * reflection) that implements the specified Method.  If no such method
0629:             * can be found, return <code>null</code>.</p>
0630:             *
0631:             * @param method The method that we wish to call
0632:             * @return The accessible method
0633:             */
0634:            public static Method getAccessibleMethod(Method method) {
0635:
0636:                // Make sure we have a method to check
0637:                if (method == null) {
0638:                    return (null);
0639:                }
0640:
0641:                // If the requested method is not public we cannot call it
0642:                if (!Modifier.isPublic(method.getModifiers())) {
0643:                    return (null);
0644:                }
0645:
0646:                // If the declaring class is public, we are done
0647:                Class clazz = method.getDeclaringClass();
0648:                if (Modifier.isPublic(clazz.getModifiers())) {
0649:                    return (method);
0650:                }
0651:
0652:                String methodName = method.getName();
0653:                Class[] parameterTypes = method.getParameterTypes();
0654:
0655:                // Check the implemented interfaces and subinterfaces
0656:                method = getAccessibleMethodFromInterfaceNest(clazz,
0657:                        methodName, parameterTypes);
0658:
0659:                // Check the superclass chain
0660:                if (method == null) {
0661:                    method = getAccessibleMethodFromSuperclass(clazz,
0662:                            methodName, parameterTypes);
0663:                }
0664:
0665:                return (method);
0666:
0667:            }
0668:
0669:            // -------------------------------------------------------- Private Methods
0670:
0671:            /**
0672:             * <p>Return an accessible method (that is, one that can be invoked via
0673:             * reflection) by scanning through the superclasses. If no such method
0674:             * can be found, return <code>null</code>.</p>
0675:             *
0676:             * @param clazz Class to be checked
0677:             * @param methodName Method name of the method we wish to call
0678:             * @param parameterTypes The parameter type signatures
0679:             */
0680:            private static Method getAccessibleMethodFromSuperclass(
0681:                    Class clazz, String methodName, Class[] parameterTypes) {
0682:
0683:                Class parentClazz = clazz.getSuperclass();
0684:                while (parentClazz != null) {
0685:                    if (Modifier.isPublic(parentClazz.getModifiers())) {
0686:                        try {
0687:                            return parentClazz.getMethod(methodName,
0688:                                    parameterTypes);
0689:                        } catch (NoSuchMethodException e) {
0690:                            return null;
0691:                        }
0692:                    }
0693:                    parentClazz = parentClazz.getSuperclass();
0694:                }
0695:                return null;
0696:            }
0697:
0698:            /**
0699:             * <p>Return an accessible method (that is, one that can be invoked via
0700:             * reflection) that implements the specified method, by scanning through
0701:             * all implemented interfaces and subinterfaces.  If no such method
0702:             * can be found, return <code>null</code>.</p>
0703:             *
0704:             * <p> There isn't any good reason why this method must be private.
0705:             * It is because there doesn't seem any reason why other classes should
0706:             * call this rather than the higher level methods.</p>
0707:             *
0708:             * @param clazz Parent class for the interfaces to be checked
0709:             * @param methodName Method name of the method we wish to call
0710:             * @param parameterTypes The parameter type signatures
0711:             */
0712:            private static Method getAccessibleMethodFromInterfaceNest(
0713:                    Class clazz, String methodName, Class[] parameterTypes) {
0714:
0715:                Method method = null;
0716:
0717:                // Search up the superclass chain
0718:                for (; clazz != null; clazz = clazz.getSuperclass()) {
0719:
0720:                    // Check the implemented interfaces of the parent class
0721:                    Class[] interfaces = clazz.getInterfaces();
0722:                    for (int i = 0; i < interfaces.length; i++) {
0723:
0724:                        // Is this interface public?
0725:                        if (!Modifier.isPublic(interfaces[i].getModifiers())) {
0726:                            continue;
0727:                        }
0728:
0729:                        // Does the method exist on this interface?
0730:                        try {
0731:                            method = interfaces[i].getDeclaredMethod(
0732:                                    methodName, parameterTypes);
0733:                        } catch (NoSuchMethodException e) {
0734:                            /* Swallow, if no method is found after the loop then this
0735:                             * method returns null.
0736:                             */
0737:                        }
0738:                        if (method != null) {
0739:                            break;
0740:                        }
0741:
0742:                        // Recursively check our parent interfaces
0743:                        method = getAccessibleMethodFromInterfaceNest(
0744:                                interfaces[i], methodName, parameterTypes);
0745:                        if (method != null) {
0746:                            break;
0747:                        }
0748:
0749:                    }
0750:
0751:                }
0752:
0753:                // If we found a method return it
0754:                if (method != null) {
0755:                    return (method);
0756:                }
0757:
0758:                // We did not find anything
0759:                return (null);
0760:
0761:            }
0762:
0763:            /**
0764:             * <p>Find an accessible method that matches the given name and has compatible parameters.
0765:             * Compatible parameters mean that every method parameter is assignable from 
0766:             * the given parameters.
0767:             * In other words, it finds a method with the given name 
0768:             * that will take the parameters given.<p>
0769:             *
0770:             * <p>This method is slightly undeterminstic since it loops 
0771:             * through methods names and return the first matching method.</p>
0772:             * 
0773:             * <p>This method is used by 
0774:             * {@link 
0775:             * #invokeMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}.
0776:             *
0777:             * <p>This method can match primitive parameter by passing in wrapper classes.
0778:             * For example, a <code>Boolean</code> will match a primitive <code>boolean</code>
0779:             * parameter.
0780:             *
0781:             * @param clazz find method in this class
0782:             * @param methodName find method with this name
0783:             * @param parameterTypes find method with compatible parameters 
0784:             * @return The accessible method
0785:             */
0786:            public static Method getMatchingAccessibleMethod(Class clazz,
0787:                    String methodName, Class[] parameterTypes) {
0788:                // trace logging
0789:                Log log = LogFactory.getLog(MethodUtils.class);
0790:                if (log.isTraceEnabled()) {
0791:                    log.trace("Matching name=" + methodName + " on " + clazz);
0792:                }
0793:                MethodDescriptor md = new MethodDescriptor(clazz, methodName,
0794:                        parameterTypes, false);
0795:
0796:                // see if we can find the method directly
0797:                // most of the time this works and it's much faster
0798:                try {
0799:                    // Check the cache first
0800:                    Method method = (Method) cache.get(md);
0801:                    if (method != null) {
0802:                        return method;
0803:                    }
0804:
0805:                    method = clazz.getMethod(methodName, parameterTypes);
0806:                    if (log.isTraceEnabled()) {
0807:                        log.trace("Found straight match: " + method);
0808:                        log.trace("isPublic:"
0809:                                + Modifier.isPublic(method.getModifiers()));
0810:                    }
0811:
0812:                    try {
0813:                        //
0814:                        // XXX Default access superclass workaround
0815:                        //
0816:                        // When a public class has a default access superclass
0817:                        // with public methods, these methods are accessible.
0818:                        // Calling them from compiled code works fine.
0819:                        //
0820:                        // Unfortunately, using reflection to invoke these methods
0821:                        // seems to (wrongly) to prevent access even when the method
0822:                        // modifer is public.
0823:                        //
0824:                        // The following workaround solves the problem but will only
0825:                        // work from sufficiently privilages code. 
0826:                        //
0827:                        // Better workarounds would be greatfully accepted.
0828:                        //
0829:                        method.setAccessible(true);
0830:
0831:                    } catch (SecurityException se) {
0832:                        // log but continue just in case the method.invoke works anyway
0833:                        if (!loggedAccessibleWarning) {
0834:                            boolean vulnerableJVM = false;
0835:                            try {
0836:                                String specVersion = System
0837:                                        .getProperty("java.specification.version");
0838:                                if (specVersion.charAt(0) == '1'
0839:                                        && (specVersion.charAt(2) == '0'
0840:                                                || specVersion.charAt(2) == '1'
0841:                                                || specVersion.charAt(2) == '2' || specVersion
0842:                                                .charAt(2) == '3')) {
0843:
0844:                                    vulnerableJVM = true;
0845:                                }
0846:                            } catch (SecurityException e) {
0847:                                // don't know - so display warning
0848:                                vulnerableJVM = true;
0849:                            }
0850:                            if (vulnerableJVM) {
0851:                                log
0852:                                        .warn("Current Security Manager restricts use of workarounds for reflection bugs "
0853:                                                + " in pre-1.4 JVMs.");
0854:                            }
0855:                            loggedAccessibleWarning = true;
0856:                        }
0857:                        log
0858:                                .debug(
0859:                                        "Cannot setAccessible on method. Therefore cannot use jvm access bug workaround.",
0860:                                        se);
0861:                    }
0862:                    cache.put(md, method);
0863:                    return method;
0864:
0865:                } catch (NoSuchMethodException e) { /* SWALLOW */
0866:                }
0867:
0868:                // search through all methods 
0869:                int paramSize = parameterTypes.length;
0870:                Method bestMatch = null;
0871:                Method[] methods = clazz.getMethods();
0872:                float bestMatchCost = Float.MAX_VALUE;
0873:                float myCost = Float.MAX_VALUE;
0874:                for (int i = 0, size = methods.length; i < size; i++) {
0875:                    if (methods[i].getName().equals(methodName)) {
0876:                        // log some trace information
0877:                        if (log.isTraceEnabled()) {
0878:                            log.trace("Found matching name:");
0879:                            log.trace(methods[i]);
0880:                        }
0881:
0882:                        // compare parameters
0883:                        Class[] methodsParams = methods[i].getParameterTypes();
0884:                        int methodParamSize = methodsParams.length;
0885:                        if (methodParamSize == paramSize) {
0886:                            boolean match = true;
0887:                            for (int n = 0; n < methodParamSize; n++) {
0888:                                if (log.isTraceEnabled()) {
0889:                                    log.trace("Param="
0890:                                            + parameterTypes[n].getName());
0891:                                    log.trace("Method="
0892:                                            + methodsParams[n].getName());
0893:                                }
0894:                                if (!isAssignmentCompatible(methodsParams[n],
0895:                                        parameterTypes[n])) {
0896:                                    if (log.isTraceEnabled()) {
0897:                                        log.trace(methodsParams[n]
0898:                                                + " is not assignable from "
0899:                                                + parameterTypes[n]);
0900:                                    }
0901:                                    match = false;
0902:                                    break;
0903:                                }
0904:                            }
0905:
0906:                            if (match) {
0907:                                // get accessible version of method
0908:                                Method method = getAccessibleMethod(methods[i]);
0909:                                if (method != null) {
0910:                                    if (log.isTraceEnabled()) {
0911:                                        log.trace(method
0912:                                                + " accessible version of "
0913:                                                + methods[i]);
0914:                                    }
0915:                                    try {
0916:                                        //
0917:                                        // XXX Default access superclass workaround
0918:                                        // (See above for more details.)
0919:                                        //
0920:                                        method.setAccessible(true);
0921:
0922:                                    } catch (SecurityException se) {
0923:                                        // log but continue just in case the method.invoke works anyway
0924:                                        if (!loggedAccessibleWarning) {
0925:                                            log
0926:                                                    .warn("Cannot use JVM pre-1.4 access bug workaround due to restrictive security manager.");
0927:                                            loggedAccessibleWarning = true;
0928:                                        }
0929:                                        log
0930:                                                .debug(
0931:                                                        "Cannot setAccessible on method. Therefore cannot use jvm access bug workaround.",
0932:                                                        se);
0933:                                    }
0934:                                    myCost = getTotalTransformationCost(
0935:                                            parameterTypes, method
0936:                                                    .getParameterTypes());
0937:                                    if (myCost < bestMatchCost) {
0938:                                        bestMatch = method;
0939:                                        bestMatchCost = myCost;
0940:                                    }
0941:                                }
0942:
0943:                                log.trace("Couldn't find accessible method.");
0944:                            }
0945:                        }
0946:                    }
0947:                }
0948:                if (bestMatch != null) {
0949:                    cache.put(md, bestMatch);
0950:                } else {
0951:                    // didn't find a match
0952:                    log.trace("No match found.");
0953:                }
0954:
0955:                return bestMatch;
0956:            }
0957:
0958:            /**
0959:             * Returns the sum of the object transformation cost for each class in the source
0960:             * argument list.
0961:             * @param srcArgs The source arguments
0962:             * @param destArgs The destination arguments
0963:             * @return The total transformation cost
0964:             */
0965:            private static float getTotalTransformationCost(Class[] srcArgs,
0966:                    Class[] destArgs) {
0967:
0968:                float totalCost = 0.0f;
0969:                for (int i = 0; i < srcArgs.length; i++) {
0970:                    Class srcClass, destClass;
0971:                    srcClass = srcArgs[i];
0972:                    destClass = destArgs[i];
0973:                    totalCost += getObjectTransformationCost(srcClass,
0974:                            destClass);
0975:                }
0976:
0977:                return totalCost;
0978:            }
0979:
0980:            /**
0981:             * Gets the number of steps required needed to turn the source class into the 
0982:             * destination class. This represents the number of steps in the object hierarchy 
0983:             * graph.
0984:             * @param srcClass The source class
0985:             * @param destClass The destination class
0986:             * @return The cost of transforming an object
0987:             */
0988:            private static float getObjectTransformationCost(Class srcClass,
0989:                    Class destClass) {
0990:                float cost = 0.0f;
0991:                while (destClass != null && !destClass.equals(srcClass)) {
0992:                    if (destClass.isInterface()
0993:                            && isAssignmentCompatible(destClass, srcClass)) {
0994:                        // slight penalty for interface match. 
0995:                        // we still want an exact match to override an interface match, but  
0996:                        // an interface match should override anything where we have to get a 
0997:                        // superclass.
0998:                        cost += 0.25f;
0999:                        break;
1000:                    }
1001:                    cost++;
1002:                    destClass = destClass.getSuperclass();
1003:                }
1004:
1005:                /*
1006:                 * If the destination class is null, we've travelled all the way up to 
1007:                 * an Object match. We'll penalize this by adding 1.5 to the cost.
1008:                 */
1009:                if (destClass == null) {
1010:                    cost += 1.5f;
1011:                }
1012:
1013:                return cost;
1014:            }
1015:
1016:            /**
1017:             * <p>Determine whether a type can be used as a parameter in a method invocation.
1018:             * This method handles primitive conversions correctly.</p>
1019:             *
1020:             * <p>In order words, it will match a <code>Boolean</code> to a <code>boolean</code>,
1021:             * a <code>Long</code> to a <code>long</code>,
1022:             * a <code>Float</code> to a <code>float</code>,
1023:             * a <code>Integer</code> to a <code>int</code>,
1024:             * and a <code>Double</code> to a <code>double</code>.
1025:             * Now logic widening matches are allowed.
1026:             * For example, a <code>Long</code> will not match a <code>int</code>.
1027:             *
1028:             * @param parameterType the type of parameter accepted by the method
1029:             * @param parameterization the type of parameter being tested 
1030:             *
1031:             * @return true if the assignement is compatible.
1032:             */
1033:            public static final boolean isAssignmentCompatible(
1034:                    Class parameterType, Class parameterization) {
1035:                // try plain assignment
1036:                if (parameterType.isAssignableFrom(parameterization)) {
1037:                    return true;
1038:                }
1039:
1040:                if (parameterType.isPrimitive()) {
1041:                    // this method does *not* do widening - you must specify exactly
1042:                    // is this the right behaviour?
1043:                    Class parameterWrapperClazz = getPrimitiveWrapper(parameterType);
1044:                    if (parameterWrapperClazz != null) {
1045:                        return parameterWrapperClazz.equals(parameterization);
1046:                    }
1047:                }
1048:
1049:                return false;
1050:            }
1051:
1052:            /**
1053:             * Gets the wrapper object class for the given primitive type class.
1054:             * For example, passing <code>boolean.class</code> returns <code>Boolean.class</code>
1055:             * @param primitiveType the primitive type class for which a match is to be found
1056:             * @return the wrapper type associated with the given primitive 
1057:             * or null if no match is found
1058:             */
1059:            public static Class getPrimitiveWrapper(Class primitiveType) {
1060:                // does anyone know a better strategy than comparing names?
1061:                if (boolean.class.equals(primitiveType)) {
1062:                    return Boolean.class;
1063:                } else if (float.class.equals(primitiveType)) {
1064:                    return Float.class;
1065:                } else if (long.class.equals(primitiveType)) {
1066:                    return Long.class;
1067:                } else if (int.class.equals(primitiveType)) {
1068:                    return Integer.class;
1069:                } else if (short.class.equals(primitiveType)) {
1070:                    return Short.class;
1071:                } else if (byte.class.equals(primitiveType)) {
1072:                    return Byte.class;
1073:                } else if (double.class.equals(primitiveType)) {
1074:                    return Double.class;
1075:                } else if (char.class.equals(primitiveType)) {
1076:                    return Character.class;
1077:                } else {
1078:
1079:                    return null;
1080:                }
1081:            }
1082:
1083:            /**
1084:             * Gets the class for the primitive type corresponding to the primitive wrapper class given.
1085:             * For example, an instance of <code>Boolean.class</code> returns a <code>boolean.class</code>. 
1086:             * @param wrapperType the 
1087:             * @return the primitive type class corresponding to the given wrapper class,
1088:             * null if no match is found
1089:             */
1090:            public static Class getPrimitiveType(Class wrapperType) {
1091:                // does anyone know a better strategy than comparing names?
1092:                if (Boolean.class.equals(wrapperType)) {
1093:                    return boolean.class;
1094:                } else if (Float.class.equals(wrapperType)) {
1095:                    return float.class;
1096:                } else if (Long.class.equals(wrapperType)) {
1097:                    return long.class;
1098:                } else if (Integer.class.equals(wrapperType)) {
1099:                    return int.class;
1100:                } else if (Short.class.equals(wrapperType)) {
1101:                    return short.class;
1102:                } else if (Byte.class.equals(wrapperType)) {
1103:                    return byte.class;
1104:                } else if (Double.class.equals(wrapperType)) {
1105:                    return double.class;
1106:                } else if (Character.class.equals(wrapperType)) {
1107:                    return char.class;
1108:                } else {
1109:                    Log log = LogFactory.getLog(MethodUtils.class);
1110:                    if (log.isDebugEnabled()) {
1111:                        log.debug("Not a known primitive wrapper class: "
1112:                                + wrapperType);
1113:                    }
1114:                    return null;
1115:                }
1116:            }
1117:
1118:            /**
1119:             * Find a non primitive representation for given primitive class.
1120:             *
1121:             * @param clazz the class to find a representation for, not null
1122:             * @return the original class if it not a primitive. Otherwise the wrapper class. Not null
1123:             */
1124:            public static Class toNonPrimitiveClass(Class clazz) {
1125:                if (clazz.isPrimitive()) {
1126:                    Class primitiveClazz = MethodUtils
1127:                            .getPrimitiveWrapper(clazz);
1128:                    // the above method returns 
1129:                    if (primitiveClazz != null) {
1130:                        return primitiveClazz;
1131:                    } else {
1132:                        return clazz;
1133:                    }
1134:                } else {
1135:                    return clazz;
1136:                }
1137:            }
1138:
1139:            /**
1140:             * Represents the key to looking up a Method by reflection.
1141:             */
1142:            private static class MethodDescriptor {
1143:                private Class cls;
1144:                private String methodName;
1145:                private Class[] paramTypes;
1146:                private boolean exact;
1147:                private int hashCode;
1148:
1149:                /**
1150:                 * The sole constructor.
1151:                 *
1152:                 * @param cls  the class to reflect, must not be null
1153:                 * @param methodName  the method name to obtain
1154:                 * @param paramTypes the array of classes representing the paramater types
1155:                 * @param exact whether the match has to be exact.
1156:                 */
1157:                public MethodDescriptor(Class cls, String methodName,
1158:                        Class[] paramTypes, boolean exact) {
1159:                    if (cls == null) {
1160:                        throw new IllegalArgumentException(
1161:                                "Class cannot be null");
1162:                    }
1163:                    if (methodName == null) {
1164:                        throw new IllegalArgumentException(
1165:                                "Method Name cannot be null");
1166:                    }
1167:                    if (paramTypes == null) {
1168:                        paramTypes = EMPTY_CLASS_PARAMETERS;
1169:                    }
1170:
1171:                    this .cls = cls;
1172:                    this .methodName = methodName;
1173:                    this .paramTypes = paramTypes;
1174:                    this .exact = exact;
1175:
1176:                    this .hashCode = methodName.length();
1177:                }
1178:
1179:                /**
1180:                 * Checks for equality.
1181:                 * @param obj object to be tested for equality
1182:                 * @return true, if the object describes the same Method.
1183:                 */
1184:                public boolean equals(Object obj) {
1185:                    if (!(obj instanceof  MethodDescriptor)) {
1186:                        return false;
1187:                    }
1188:                    MethodDescriptor md = (MethodDescriptor) obj;
1189:
1190:                    return (exact == md.exact
1191:                            && methodName.equals(md.methodName)
1192:                            && cls.equals(md.cls) && java.util.Arrays.equals(
1193:                            paramTypes, md.paramTypes));
1194:                }
1195:
1196:                /**
1197:                 * Returns the string length of method name. I.e. if the
1198:                 * hashcodes are different, the objects are different. If the
1199:                 * hashcodes are the same, need to use the equals method to
1200:                 * determine equality.
1201:                 * @return the string length of method name.
1202:                 */
1203:                public int hashCode() {
1204:                    return hashCode;
1205:                }
1206:            }
1207:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.