Source Code Cross Referenced for ConstructorUtils.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) 


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:
018:        package org.apache.commons.beanutils;
019:
020:        import java.lang.reflect.Constructor;
021:        import java.lang.reflect.InvocationTargetException;
022:        import java.lang.reflect.Modifier;
023:
024:        /**
025:         * <p> Utility reflection methods focussed on constructors, modelled after {@link MethodUtils}. </p>
026:         *
027:         * <h3>Known Limitations</h3>
028:         * <h4>Accessing Public Constructors In A Default Access Superclass</h4>
029:         * <p>There is an issue when invoking public constructors contained in a default access superclass.
030:         * Reflection locates these constructors fine and correctly assigns them as public.
031:         * However, an <code>IllegalAccessException</code> is thrown if the constructors is invoked.</p>
032:         *
033:         * <p><code>ConstructorUtils</code> contains a workaround for this situation.
034:         * It will attempt to call <code>setAccessible</code> on this constructor.
035:         * If this call succeeds, then the method can be invoked as normal.
036:         * This call will only succeed when the application has sufficient security privilages.
037:         * If this call fails then a warning will be logged and the method may fail.</p>
038:         *
039:         * @author Craig R. McClanahan
040:         * @author Ralph Schaer
041:         * @author Chris Audley
042:         * @author Rey Francois
043:         * @author Gregor Rayman
044:         * @author Jan Sorensen
045:         * @author Robert Burrell Donkin
046:         * @author Rodney Waldhoff
047:         * @version $Revision: 555824 $ $Date: 2007-07-13 01:27:15 +0100 (Fri, 13 Jul 2007) $
048:         */
049:        public class ConstructorUtils {
050:
051:            // --------------------------------------------------------- Private Members
052:            /** An empty class array */
053:            private static final Class[] EMPTY_CLASS_PARAMETERS = new Class[0];
054:            /** An empty object array */
055:            private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
056:
057:            // --------------------------------------------------------- Public Methods
058:
059:            /**
060:             * <p>Convenience method returning new instance of <code>klazz</code> using a single argument constructor.
061:             * The formal parameter type is inferred from the actual values of <code>arg</code>.
062:             * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
063:             *
064:             * <p>The signatures should be assignment compatible.</p>
065:             *
066:             * @param klass the class to be constructed.
067:             * @param arg the actual argument
068:             * @return new instance of <code>klazz</code>
069:             *
070:             * @throws NoSuchMethodException If the constructor cannot be found
071:             * @throws IllegalAccessException If an error occurs accessing the constructor
072:             * @throws InvocationTargetException If an error occurs invoking the constructor
073:             * @throws InstantiationException If an error occurs instantiating the class
074:             *
075:             * @see #invokeConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
076:             */
077:            public static Object invokeConstructor(Class klass, Object arg)
078:                    throws NoSuchMethodException, IllegalAccessException,
079:                    InvocationTargetException, InstantiationException {
080:
081:                Object[] args = { arg };
082:                return invokeConstructor(klass, args);
083:
084:            }
085:
086:            /**
087:             * <p>Returns new instance of <code>klazz</code> created using the actual arguments <code>args</code>.
088:             * The formal parameter types are inferred from the actual values of <code>args</code>.
089:             * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
090:             *
091:             * <p>The signatures should be assignment compatible.</p>
092:             *
093:             * @param klass the class to be constructed.
094:             * @param args actual argument array
095:             * @return new instance of <code>klazz</code>
096:             *
097:             * @throws NoSuchMethodException If the constructor cannot be found
098:             * @throws IllegalAccessException If an error occurs accessing the constructor
099:             * @throws InvocationTargetException If an error occurs invoking the constructor
100:             * @throws InstantiationException If an error occurs instantiating the class
101:             *
102:             * @see #invokeConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
103:             */
104:            public static Object invokeConstructor(Class klass, Object[] args)
105:                    throws NoSuchMethodException, IllegalAccessException,
106:                    InvocationTargetException, InstantiationException {
107:
108:                if (null == args) {
109:                    args = EMPTY_OBJECT_ARRAY;
110:                }
111:                int arguments = args.length;
112:                Class parameterTypes[] = new Class[arguments];
113:                for (int i = 0; i < arguments; i++) {
114:                    parameterTypes[i] = args[i].getClass();
115:                }
116:                return invokeConstructor(klass, args, parameterTypes);
117:
118:            }
119:
120:            /**
121:             * <p>Returns new instance of <code>klazz</code> created using constructor
122:             * with signature <code>parameterTypes</code> and actual arguments <code>args</code>.</p>
123:             *
124:             * <p>The signatures should be assignment compatible.</p>
125:             *
126:             * @param klass the class to be constructed.
127:             * @param args actual argument array
128:             * @param parameterTypes parameter types array
129:             * @return new instance of <code>klazz</code>
130:             *
131:             * @throws NoSuchMethodException if matching constructor cannot be found
132:             * @throws IllegalAccessException thrown on the constructor's invocation
133:             * @throws InvocationTargetException thrown on the constructor's invocation
134:             * @throws InstantiationException thrown on the constructor's invocation
135:             * @see Constructor#newInstance
136:             */
137:            public static Object invokeConstructor(Class klass, Object[] args,
138:                    Class[] parameterTypes) throws NoSuchMethodException,
139:                    IllegalAccessException, InvocationTargetException,
140:                    InstantiationException {
141:
142:                if (parameterTypes == null) {
143:                    parameterTypes = EMPTY_CLASS_PARAMETERS;
144:                }
145:                if (args == null) {
146:                    args = EMPTY_OBJECT_ARRAY;
147:                }
148:
149:                Constructor ctor = getMatchingAccessibleConstructor(klass,
150:                        parameterTypes);
151:                if (null == ctor) {
152:                    throw new NoSuchMethodException(
153:                            "No such accessible constructor on object: "
154:                                    + klass.getName());
155:                }
156:                return ctor.newInstance(args);
157:            }
158:
159:            /**
160:             * <p>Convenience method returning new instance of <code>klazz</code> using a single argument constructor.
161:             * The formal parameter type is inferred from the actual values of <code>arg</code>.
162:             * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
163:             *
164:             * <p>The signatures should match exactly.</p>
165:             *
166:             * @param klass the class to be constructed.
167:             * @param arg the actual argument
168:             * @return new instance of <code>klazz</code>
169:             *
170:             * @throws NoSuchMethodException If the constructor cannot be found
171:             * @throws IllegalAccessException If an error occurs accessing the constructor
172:             * @throws InvocationTargetException If an error occurs invoking the constructor
173:             * @throws InstantiationException If an error occurs instantiating the class
174:             *
175:             * @see #invokeExactConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
176:             */
177:            public static Object invokeExactConstructor(Class klass, Object arg)
178:                    throws NoSuchMethodException, IllegalAccessException,
179:                    InvocationTargetException, InstantiationException {
180:
181:                Object[] args = { arg };
182:                return invokeExactConstructor(klass, args);
183:
184:            }
185:
186:            /**
187:             * <p>Returns new instance of <code>klazz</code> created using the actual arguments <code>args</code>.
188:             * The formal parameter types are inferred from the actual values of <code>args</code>.
189:             * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
190:             *
191:             * <p>The signatures should match exactly.</p>
192:             *
193:             * @param klass the class to be constructed.
194:             * @param args actual argument array
195:             * @return new instance of <code>klazz</code>
196:             *
197:             * @throws NoSuchMethodException If the constructor cannot be found
198:             * @throws IllegalAccessException If an error occurs accessing the constructor
199:             * @throws InvocationTargetException If an error occurs invoking the constructor
200:             * @throws InstantiationException If an error occurs instantiating the class
201:             *
202:             * @see #invokeExactConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
203:             */
204:            public static Object invokeExactConstructor(Class klass,
205:                    Object[] args) throws NoSuchMethodException,
206:                    IllegalAccessException, InvocationTargetException,
207:                    InstantiationException {
208:                if (null == args) {
209:                    args = EMPTY_OBJECT_ARRAY;
210:                }
211:                int arguments = args.length;
212:                Class parameterTypes[] = new Class[arguments];
213:                for (int i = 0; i < arguments; i++) {
214:                    parameterTypes[i] = args[i].getClass();
215:                }
216:                return invokeExactConstructor(klass, args, parameterTypes);
217:
218:            }
219:
220:            /**
221:             * <p>Returns new instance of <code>klazz</code> created using constructor
222:             * with signature <code>parameterTypes</code> and actual arguments
223:             * <code>args</code>.</p>
224:             *
225:             * <p>The signatures should match exactly.</p>
226:             *
227:             * @param klass the class to be constructed.
228:             * @param args actual argument array
229:             * @param parameterTypes parameter types array
230:             * @return new instance of <code>klazz</code>
231:             *
232:             * @throws NoSuchMethodException if matching constructor cannot be found
233:             * @throws IllegalAccessException thrown on the constructor's invocation
234:             * @throws InvocationTargetException thrown on the constructor's invocation
235:             * @throws InstantiationException thrown on the constructor's invocation
236:             * @see Constructor#newInstance
237:             */
238:            public static Object invokeExactConstructor(Class klass,
239:                    Object[] args, Class[] parameterTypes)
240:                    throws NoSuchMethodException, IllegalAccessException,
241:                    InvocationTargetException, InstantiationException {
242:
243:                if (args == null) {
244:                    args = EMPTY_OBJECT_ARRAY;
245:                }
246:
247:                if (parameterTypes == null) {
248:                    parameterTypes = EMPTY_CLASS_PARAMETERS;
249:                }
250:
251:                Constructor ctor = getAccessibleConstructor(klass,
252:                        parameterTypes);
253:                if (null == ctor) {
254:                    throw new NoSuchMethodException(
255:                            "No such accessible constructor on object: "
256:                                    + klass.getName());
257:                }
258:                return ctor.newInstance(args);
259:
260:            }
261:
262:            /**
263:             * Returns a constructor with single argument.
264:             * @param klass the class to be constructed
265:             * @param parameterType The constructor parameter type
266:             * @return null if matching accessible constructor can not be found.
267:             * @see Class#getConstructor
268:             * @see #getAccessibleConstructor(java.lang.reflect.Constructor)
269:             */
270:            public static Constructor getAccessibleConstructor(Class klass,
271:                    Class parameterType) {
272:
273:                Class[] parameterTypes = { parameterType };
274:                return getAccessibleConstructor(klass, parameterTypes);
275:
276:            }
277:
278:            /**
279:             * Returns a constructor given a class and signature.
280:             * @param klass the class to be constructed
281:             * @param parameterTypes the parameter array
282:             * @return null if matching accessible constructor can not be found
283:             * @see Class#getConstructor
284:             * @see #getAccessibleConstructor(java.lang.reflect.Constructor)
285:             */
286:            public static Constructor getAccessibleConstructor(Class klass,
287:                    Class[] parameterTypes) {
288:
289:                try {
290:                    return getAccessibleConstructor(klass
291:                            .getConstructor(parameterTypes));
292:                } catch (NoSuchMethodException e) {
293:                    return (null);
294:                }
295:
296:            }
297:
298:            /**
299:             * Returns accessible version of the given constructor.
300:             * @param ctor prototype constructor object.
301:             * @return <code>null</code> if accessible constructor can not be found.
302:             * @see java.lang.SecurityManager
303:             */
304:            public static Constructor getAccessibleConstructor(Constructor ctor) {
305:
306:                // Make sure we have a method to check
307:                if (ctor == null) {
308:                    return (null);
309:                }
310:
311:                // If the requested method is not public we cannot call it
312:                if (!Modifier.isPublic(ctor.getModifiers())) {
313:                    return (null);
314:                }
315:
316:                // If the declaring class is public, we are done
317:                Class clazz = ctor.getDeclaringClass();
318:                if (Modifier.isPublic(clazz.getModifiers())) {
319:                    return (ctor);
320:                }
321:
322:                // what else can we do?
323:                return null;
324:
325:            }
326:
327:            // -------------------------------------------------------- Private Methods
328:            /**
329:             * <p>Find an accessible constructor with compatible parameters.
330:             * Compatible parameters mean that every method parameter is assignable from
331:             * the given parameters. In other words, it finds constructor that will take
332:             * the parameters given.</p>
333:             *
334:             * <p>First it checks if there is constructor matching the exact signature.
335:             * If no such, all the constructors of the class are tested if their signatures
336:             * are assignment compatible with the parameter types.
337:             * The first matching constructor is returned.</p>
338:             *
339:             * @param clazz find constructor for this class
340:             * @param parameterTypes find method with compatible parameters
341:             * @return a valid Constructor object. If there's no matching constructor, returns <code>null</code>.
342:             */
343:            private static Constructor getMatchingAccessibleConstructor(
344:                    Class clazz, Class[] parameterTypes) {
345:                // see if we can find the method directly
346:                // most of the time this works and it's much faster
347:                try {
348:                    Constructor ctor = clazz.getConstructor(parameterTypes);
349:                    try {
350:                        //
351:                        // XXX Default access superclass workaround
352:                        //
353:                        // When a public class has a default access superclass
354:                        // with public methods, these methods are accessible.
355:                        // Calling them from compiled code works fine.
356:                        //
357:                        // Unfortunately, using reflection to invoke these methods
358:                        // seems to (wrongly) to prevent access even when the method
359:                        // modifer is public.
360:                        //
361:                        // The following workaround solves the problem but will only
362:                        // work from sufficiently privilages code. 
363:                        //
364:                        // Better workarounds would be greatfully accepted.
365:                        //
366:                        ctor.setAccessible(true);
367:                    } catch (SecurityException se) {
368:                        /* SWALLOW, if workaround fails don't fret. */
369:                    }
370:                    return ctor;
371:
372:                } catch (NoSuchMethodException e) { /* SWALLOW */
373:                }
374:
375:                // search through all methods 
376:                int paramSize = parameterTypes.length;
377:                Constructor[] ctors = clazz.getConstructors();
378:                for (int i = 0, size = ctors.length; i < size; i++) {
379:                    // compare parameters
380:                    Class[] ctorParams = ctors[i].getParameterTypes();
381:                    int ctorParamSize = ctorParams.length;
382:                    if (ctorParamSize == paramSize) {
383:                        boolean match = true;
384:                        for (int n = 0; n < ctorParamSize; n++) {
385:                            if (!MethodUtils.isAssignmentCompatible(
386:                                    ctorParams[n], parameterTypes[n])) {
387:                                match = false;
388:                                break;
389:                            }
390:                        }
391:
392:                        if (match) {
393:                            // get accessible version of method
394:                            Constructor ctor = getAccessibleConstructor(ctors[i]);
395:                            if (ctor != null) {
396:                                try {
397:                                    ctor.setAccessible(true);
398:                                } catch (SecurityException se) {
399:                                    /* Swallow SecurityException
400:                                     * TODO: Why?
401:                                     */
402:                                }
403:                                return ctor;
404:                            }
405:                        }
406:                    }
407:                }
408:
409:                return null;
410:            }
411:
412:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.