KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > util > ClassHelper


1 package org.apache.ojb.broker.util;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Field JavaDoc;
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.lang.reflect.Modifier JavaDoc;
23 import java.net.URL JavaDoc;
24
25 import org.apache.ojb.broker.OJBRuntimeException;
26 import org.apache.ojb.broker.PersistenceBrokerException;
27 import org.apache.ojb.broker.metadata.ClassDescriptor;
28 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
29
30 /**
31  * Helper class with static methods for java class, method, and field handling.
32  *
33  * @version $Id: ClassHelper.java,v 1.10.2.3 2005/12/21 22:27:47 tomdz Exp $
34  */

35 public class ClassHelper
36 {
37     /** Arguments for invoking a default or no-arg constructor */
38     private static final Object JavaDoc[] NO_ARGS = {};
39     /** Parameter types of a default/no-arg constructor */
40     private static final Class JavaDoc[] NO_ARGS_CLASS = {};
41
42     /** The class loader currently used by OJB */
43     private static ClassLoader JavaDoc _classLoader = null;
44     /** A mutex for changing the class loader */
45     private static Object JavaDoc _mutex = new Object JavaDoc();
46     
47     /**
48      * Prevents instatiation.
49      */

50     private ClassHelper()
51     {
52     }
53
54     /**
55      * Sets the classloader to be used by OJB. This can be set by external
56      * application that need to pass a specific classloader to OJB.
57      *
58      * @param loader The class loader. If <code>null</code> then OJB will use
59      * the class loader of the current thread
60      */

61     public static void setClassLoader(ClassLoader JavaDoc loader)
62     {
63         synchronized (_mutex)
64         {
65             _classLoader = loader;
66         }
67     }
68
69     /**
70      * Returns the class loader currently used by OJB. Defaults to the class loader of
71      * the current thread (<code>Thread.currentThread().getContextClassLoader()</code>)
72      * if not set differently. If class loader is not explicitly set and the loader for
73      * the current thread context is null, the JVM default class loader will be used.
74      *
75      * @return The classloader used by OJB
76      * @see #setClassLoader(ClassLoader)
77      */

78     public static ClassLoader JavaDoc getClassLoader()
79     {
80         final ClassLoader JavaDoc ojbClassLoader;
81         if (_classLoader != null)
82         {
83             ojbClassLoader = _classLoader;
84         }
85         else
86         {
87             final ClassLoader JavaDoc threadCtxtClassLoader;
88             threadCtxtClassLoader = Thread.currentThread().getContextClassLoader();
89             if (threadCtxtClassLoader == null)
90             {
91                 // mkalen: happens only in "obscure" situations using JNI, revert to system CL
92
ojbClassLoader = ClassLoader.getSystemClassLoader();
93             }
94             else
95             {
96                 ojbClassLoader = threadCtxtClassLoader;
97             }
98         }
99         return ojbClassLoader;
100     }
101
102     /**
103      * Determines the url of the indicated resource using the currently set class loader.
104      *
105      * @param name The resource name
106      * @return The resource's url
107      */

108     public static URL JavaDoc getResource(String JavaDoc name)
109     {
110         return getClassLoader().getResource(name);
111     }
112     
113     /**
114      * Retrieves the class object for the given qualified class name.
115      *
116      * @param className The qualified name of the class
117      * @param initialize Whether the class shall be initialized
118      * @return The class object
119      */

120     public static Class JavaDoc getClass(String JavaDoc className, boolean initialize) throws ClassNotFoundException JavaDoc
121     {
122         return Class.forName(className, initialize, getClassLoader());
123     }
124
125     /**
126      * Returns a new instance of the given class, using the default or a no-arg constructor.
127      *
128      * @param target The class to instantiate
129      * @return The instance
130      */

131     public static Object JavaDoc newInstance(Class JavaDoc target) throws InstantiationException JavaDoc,
132                                                           IllegalAccessException JavaDoc
133     {
134         return target.newInstance();
135     }
136
137     /**
138      * Returns a new instance of the given class, using the default or a no-arg constructor.
139      * This method can also use private no-arg constructors if <code>makeAccessible</code>
140      * is set to <code>true</code> (and there are no other security constraints).
141      *
142      * @param target The class to instantiate
143      * @param makeAccessible If the constructor shall be made accessible prior to using it
144      * @return The instance
145      */

146     public static Object JavaDoc newInstance(Class JavaDoc target, boolean makeAccessible) throws InstantiationException JavaDoc,
147                                                                                   IllegalAccessException JavaDoc
148     {
149         if (makeAccessible)
150         {
151             try
152             {
153                 return newInstance(target, NO_ARGS_CLASS, NO_ARGS, makeAccessible);
154             }
155             catch (InvocationTargetException JavaDoc e)
156             {
157                 throw new OJBRuntimeException("Unexpected exception while instantiate class '"
158                         + target + "' with default constructor", e);
159             }
160             catch (NoSuchMethodException JavaDoc e)
161             {
162                 throw new OJBRuntimeException("Unexpected exception while instantiate class '"
163                         + target + "' with default constructor", e);
164             }
165         }
166         else
167         {
168             return target.newInstance();
169         }
170     }
171
172     /**
173      * Returns a new instance of the given class, using the constructor with the specified parameter types.
174      *
175      * @param target The class to instantiate
176      * @param types The parameter types
177      * @param args The arguments
178      * @return The instance
179      */

180     public static Object JavaDoc newInstance(Class JavaDoc target, Class JavaDoc[] types, Object JavaDoc[] args) throws InstantiationException JavaDoc,
181                                                                                         IllegalAccessException JavaDoc,
182                                                                                         IllegalArgumentException JavaDoc,
183                                                                                         InvocationTargetException JavaDoc,
184                                                                                         NoSuchMethodException JavaDoc,
185                                                                                         SecurityException JavaDoc
186     {
187         return newInstance(target, types, args, false);
188     }
189
190     /**
191      * Returns a new instance of the given class, using the constructor with the specified parameter types.
192      * This method can also use private constructors if <code>makeAccessible</code> is set to
193      * <code>true</code> (and there are no other security constraints).
194      *
195      * @param target The class to instantiate
196      * @param types The parameter types
197      * @param args The arguments
198      * @param makeAccessible If the constructor shall be made accessible prior to using it
199      * @return The instance
200      */

201     public static Object JavaDoc newInstance(Class JavaDoc target, Class JavaDoc[] types, Object JavaDoc[] args, boolean makeAccessible) throws InstantiationException JavaDoc,
202                                                                                                                 IllegalAccessException JavaDoc,
203                                                                                                                 IllegalArgumentException JavaDoc,
204                                                                                                                 InvocationTargetException JavaDoc,
205                                                                                                                 NoSuchMethodException JavaDoc,
206                                                                                                                 SecurityException JavaDoc
207     {
208         Constructor JavaDoc con;
209
210         if (makeAccessible)
211         {
212             con = target.getDeclaredConstructor(types);
213             if (makeAccessible && !con.isAccessible())
214             {
215                 con.setAccessible(true);
216             }
217         }
218         else
219         {
220             con = target.getConstructor(types);
221         }
222         return con.newInstance(args);
223     }
224
225     /**
226      * Determines the method with the specified signature via reflection look-up.
227      *
228      * @param clazz The java class to search in
229      * @param methodName The method's name
230      * @param params The parameter types
231      * @return The method object or <code>null</code> if no matching method was found
232      */

233     public static Method JavaDoc getMethod(Class JavaDoc clazz, String JavaDoc methodName, Class JavaDoc[] params)
234     {
235         try
236         {
237             return clazz.getMethod(methodName, params);
238         }
239         catch (Exception JavaDoc ignored)
240         {}
241         return null;
242     }
243
244     /**
245      * Determines the field via reflection look-up.
246      *
247      * @param clazz The java class to search in
248      * @param fieldName The field's name
249      * @return The field object or <code>null</code> if no matching field was found
250      */

251     public static Field JavaDoc getField(Class JavaDoc clazz, String JavaDoc fieldName)
252     {
253         try
254         {
255             return clazz.getField(fieldName);
256         }
257         catch (Exception JavaDoc ignored)
258         {}
259         return null;
260     }
261
262
263     // *******************************************************************
264
// Convenience methods
265
// *******************************************************************
266

267     /**
268      * Convenience method for {@link #getClass(String, boolean) getClass(name, true)}
269      *
270      * @param name The qualified class name
271      * @return The class object
272      */

273     public static Class JavaDoc getClass(String JavaDoc name) throws ClassNotFoundException JavaDoc
274     {
275         return getClass(name, true);
276     }
277
278
279     /**
280      * Returns a new instance of the class with the given qualified name using the default or
281      * or a no-arg constructor.
282      *
283      * @param className The qualified name of the class to instantiate
284      */

285     public static Object JavaDoc newInstance(String JavaDoc className) throws InstantiationException JavaDoc,
286                                                               IllegalAccessException JavaDoc,
287                                                               ClassNotFoundException JavaDoc
288     {
289         return newInstance(getClass(className));
290     }
291
292     /**
293      * Returns a new instance of the class with the given qualified name using the constructor with
294      * the specified signature.
295      *
296      * @param className The qualified name of the class to instantiate
297      * @param types The parameter types
298      * @param args The arguments
299      * @return The instance
300      */

301     public static Object JavaDoc newInstance(String JavaDoc className, Class JavaDoc[] types, Object JavaDoc[] args) throws InstantiationException JavaDoc,
302                                                                                             IllegalAccessException JavaDoc,
303                                                                                             IllegalArgumentException JavaDoc,
304                                                                                             InvocationTargetException JavaDoc,
305                                                                                             NoSuchMethodException JavaDoc,
306                                                                                             SecurityException JavaDoc,
307                                                                                             ClassNotFoundException JavaDoc
308     {
309         return newInstance(getClass(className), types, args);
310     }
311
312     /**
313      * Returns a new instance of the given class using the constructor with the specified parameter.
314      *
315      * @param target The class to instantiate
316      * @param type The types of the single parameter of the constructor
317      * @param arg The argument
318      * @return The instance
319      */

320     public static Object JavaDoc newInstance(Class JavaDoc target, Class JavaDoc type, Object JavaDoc arg) throws InstantiationException JavaDoc,
321                                                                                   IllegalAccessException JavaDoc,
322                                                                                   IllegalArgumentException JavaDoc,
323                                                                                   InvocationTargetException JavaDoc,
324                                                                                   NoSuchMethodException JavaDoc,
325                                                                                   SecurityException JavaDoc
326     {
327         return newInstance(target, new Class JavaDoc[]{ type }, new Object JavaDoc[]{ arg });
328     }
329
330     /**
331      * Returns a new instance of the class with the given qualified name using the constructor with
332      * the specified parameter.
333      *
334      * @param className The qualified name of the class to instantiate
335      * @param type The types of the single parameter of the constructor
336      * @param arg The argument
337      * @return The instance
338      */

339     public static Object JavaDoc newInstance(String JavaDoc className, Class JavaDoc type, Object JavaDoc arg) throws InstantiationException JavaDoc,
340                                                                                       IllegalAccessException JavaDoc,
341                                                                                       IllegalArgumentException JavaDoc,
342                                                                                       InvocationTargetException JavaDoc,
343                                                                                       NoSuchMethodException JavaDoc,
344                                                                                       SecurityException JavaDoc,
345                                                                                       ClassNotFoundException JavaDoc
346     {
347         return newInstance(className, new Class JavaDoc[]{type}, new Object JavaDoc[]{arg});
348     }
349
350     /**
351      * Determines the method with the specified signature via reflection look-up.
352      *
353      * @param object The instance whose class is searched for the method
354      * @param methodName The method's name
355      * @param params The parameter types
356      * @return A method object or <code>null</code> if no matching method was found
357      */

358     public static Method JavaDoc getMethod(Object JavaDoc object, String JavaDoc methodName, Class JavaDoc[] params)
359     {
360         return getMethod(object.getClass(), methodName, params);
361     }
362
363     /**
364      * Determines the method with the specified signature via reflection look-up.
365      *
366      * @param className The qualified name of the searched class
367      * @param methodName The method's name
368      * @param params The parameter types
369      * @return A method object or <code>null</code> if no matching method was found
370      */

371     public static Method JavaDoc getMethod(String JavaDoc className, String JavaDoc methodName, Class JavaDoc[] params)
372     {
373         try
374         {
375             return getMethod(getClass(className, false), methodName, params);
376         }
377         catch (Exception JavaDoc ignored)
378         {}
379         return null;
380     }
381
382     /**
383      * Builds a new instance for the class represented by the given class descriptor.
384      *
385      * @param cld The class descriptor
386      * @return The instance
387      */

388     public static Object JavaDoc buildNewObjectInstance(ClassDescriptor cld)
389     {
390         Object JavaDoc result = null;
391
392         // If either the factory class and/or factory method is null,
393
// just follow the normal code path and create via constructor
394
if ((cld.getFactoryClass() == null) || (cld.getFactoryMethod() == null))
395         {
396             try
397             {
398                 // 1. create an empty Object (persistent classes need a public default constructor)
399
Constructor JavaDoc con = cld.getZeroArgumentConstructor();
400                 if(con == null)
401                 {
402                     throw new ClassNotPersistenceCapableException(
403                     "A zero argument constructor was not provided! Class was '" + cld.getClassNameOfObject() + "'");
404                 }
405                 result = ConstructorHelper.instantiate(con);
406             }
407             catch (InstantiationException JavaDoc e)
408             {
409                 throw new ClassNotPersistenceCapableException(
410                         "Can't instantiate class '" + cld.getClassNameOfObject()+"'");
411             }
412         }
413         else
414         {
415             try
416             {
417                 // 1. create an empty Object by calling the no-parms factory method
418
Method JavaDoc method = cld.getFactoryMethod();
419
420                 if (Modifier.isStatic(method.getModifiers()))
421                 {
422                     // method is static so call it directly
423
result = method.invoke(null, null);
424                 }
425                 else
426                 {
427                     // method is not static, so create an object of the factory first
428
// note that this requires a public no-parameter (default) constructor
429
Object JavaDoc factoryInstance = cld.getFactoryClass().newInstance();
430
431                     result = method.invoke(factoryInstance, null);
432                 }
433             }
434             catch (Exception JavaDoc ex)
435             {
436                 throw new PersistenceBrokerException("Unable to build object instance of class '"
437                         + cld.getClassNameOfObject() + "' from factory:" + cld.getFactoryClass()
438                         + "." + cld.getFactoryMethod(), ex);
439             }
440         }
441         return result;
442     }
443 }
444
Popular Tags