1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.util;
20
21 import javax.el.ExpressionFactory;
22 import javax.faces.FacesException;
23 import javax.faces.context.FacesContext;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.lang.reflect.Array;
27 import java.lang.reflect.Constructor;
28 import java.lang.reflect.InvocationTargetException;
29 import java.net.URL;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Enumeration;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.logging.Level;
39 import java.util.logging.Logger;
40
41
42
43
44
45
46
47 public final class ClassUtils
48 {
49
50
51
52 private static final Logger log = Logger.getLogger(ClassUtils.class.getName());
53
54 public static final Class BOOLEAN_ARRAY_CLASS = boolean[].class;
55 public static final Class BYTE_ARRAY_CLASS = byte[].class;
56 public static final Class CHAR_ARRAY_CLASS = char[].class;
57 public static final Class SHORT_ARRAY_CLASS = short[].class;
58 public static final Class INT_ARRAY_CLASS = int[].class;
59 public static final Class LONG_ARRAY_CLASS = long[].class;
60 public static final Class FLOAT_ARRAY_CLASS = float[].class;
61 public static final Class DOUBLE_ARRAY_CLASS = double[].class;
62 public static final Class OBJECT_ARRAY_CLASS = Object[].class;
63 public static final Class BOOLEAN_OBJECT_ARRAY_CLASS = Boolean[].class;
64 public static final Class BYTE_OBJECT_ARRAY_CLASS = Byte[].class;
65 public static final Class CHARACTER_OBJECT_ARRAY_CLASS = Character[].class;
66 public static final Class SHORT_OBJECT_ARRAY_CLASS = Short[].class;
67 public static final Class INTEGER_OBJECT_ARRAY_CLASS = Integer[].class;
68 public static final Class LONG_OBJECT_ARRAY_CLASS = Long[].class;
69 public static final Class FLOAT_OBJECT_ARRAY_CLASS = Float[].class;
70 public static final Class DOUBLE_OBJECT_ARRAY_CLASS = Double[].class;
71 public static final Class STRING_OBJECT_ARRAY_CLASS = String[].class;
72
73 public static ClassLoaderExtension [] classLoadingExtensions = new ClassLoaderExtension[0];
74
75
76
77 public static final Map COMMON_TYPES = new HashMap(64);
78 static
79 {
80 COMMON_TYPES.put("byte", Byte.TYPE);
81 COMMON_TYPES.put("char", Character.TYPE);
82 COMMON_TYPES.put("double", Double.TYPE);
83 COMMON_TYPES.put("float", Float.TYPE);
84 COMMON_TYPES.put("int", Integer.TYPE);
85 COMMON_TYPES.put("long", Long.TYPE);
86 COMMON_TYPES.put("short", Short.TYPE);
87 COMMON_TYPES.put("boolean", Boolean.TYPE);
88 COMMON_TYPES.put("void", Void.TYPE);
89 COMMON_TYPES.put("java.lang.Object", Object.class);
90 COMMON_TYPES.put("java.lang.Boolean", Boolean.class);
91 COMMON_TYPES.put("java.lang.Byte", Byte.class);
92 COMMON_TYPES.put("java.lang.Character", Character.class);
93 COMMON_TYPES.put("java.lang.Short", Short.class);
94 COMMON_TYPES.put("java.lang.Integer", Integer.class);
95 COMMON_TYPES.put("java.lang.Long", Long.class);
96 COMMON_TYPES.put("java.lang.Float", Float.class);
97 COMMON_TYPES.put("java.lang.Double", Double.class);
98 COMMON_TYPES.put("java.lang.String", String.class);
99
100 COMMON_TYPES.put("byte[]", BYTE_ARRAY_CLASS);
101 COMMON_TYPES.put("char[]", CHAR_ARRAY_CLASS);
102 COMMON_TYPES.put("double[]", DOUBLE_ARRAY_CLASS);
103 COMMON_TYPES.put("float[]", FLOAT_ARRAY_CLASS);
104 COMMON_TYPES.put("int[]", INT_ARRAY_CLASS);
105 COMMON_TYPES.put("long[]", LONG_ARRAY_CLASS);
106 COMMON_TYPES.put("short[]", SHORT_ARRAY_CLASS);
107 COMMON_TYPES.put("boolean[]", BOOLEAN_ARRAY_CLASS);
108 COMMON_TYPES.put("java.lang.Object[]", OBJECT_ARRAY_CLASS);
109 COMMON_TYPES.put("java.lang.Boolean[]", BOOLEAN_OBJECT_ARRAY_CLASS);
110 COMMON_TYPES.put("java.lang.Byte[]", BYTE_OBJECT_ARRAY_CLASS);
111 COMMON_TYPES.put("java.lang.Character[]", CHARACTER_OBJECT_ARRAY_CLASS);
112 COMMON_TYPES.put("java.lang.Short[]", SHORT_OBJECT_ARRAY_CLASS);
113 COMMON_TYPES.put("java.lang.Integer[]", INTEGER_OBJECT_ARRAY_CLASS);
114 COMMON_TYPES.put("java.lang.Long[]", LONG_OBJECT_ARRAY_CLASS);
115 COMMON_TYPES.put("java.lang.Float[]", FLOAT_OBJECT_ARRAY_CLASS);
116 COMMON_TYPES.put("java.lang.Double[]", DOUBLE_OBJECT_ARRAY_CLASS);
117 COMMON_TYPES.put("java.lang.String[]", STRING_OBJECT_ARRAY_CLASS);
118
119 }
120
121
122 private ClassUtils()
123 {
124
125 }
126
127
128
129 public synchronized static void addClassLoadingExtension(ClassLoaderExtension extension, boolean top) {
130
131
132
133
134
135
136
137
138 ClassLoaderExtension [] retVal = new ClassLoaderExtension[classLoadingExtensions.length+1];
139 ArrayList extensions = new ArrayList(classLoadingExtensions.length+1);
140
141 if(!top) {
142 extensions.addAll(Arrays.asList(classLoadingExtensions));
143 }
144 extensions.add(extension);
145 if(top) {
146 extensions.addAll(Arrays.asList(classLoadingExtensions));
147 }
148
149 classLoadingExtensions = (ClassLoaderExtension []) extensions.toArray(retVal);
150 }
151
152
153
154
155
156
157
158
159
160
161
162 public static Class classForName(String type)
163 throws ClassNotFoundException
164 {
165
166
167
168 ClassLoaderExtension [] loaderPlugins = classLoadingExtensions;
169
170 int plugins = loaderPlugins.length;
171 for(int cnt = 0; cnt < loaderPlugins.length; cnt ++) {
172 ClassLoaderExtension extension = loaderPlugins[cnt];
173 Class retVal = extension.forName(type);
174 if(retVal != null) {
175 return retVal;
176 }
177 }
178
179
180 if (type == null) throw new NullPointerException("type");
181 try
182 {
183
184 return Class.forName(type,
185 false,
186 getContextClassLoader());
187 }
188 catch (ClassNotFoundException ignore)
189 {
190
191 return Class.forName(type,
192 false,
193 ClassUtils.class.getClassLoader());
194 }
195 }
196
197
198
199
200
201
202
203
204
205
206 public static Class simpleClassForName(String type)
207 {
208 try
209 {
210 return classForName(type);
211 }
212 catch (ClassNotFoundException e)
213 {
214 log.log(Level.SEVERE, "Class " + type + " not found", e);
215 throw new FacesException(e);
216 }
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230 public static Class javaTypeToClass(String type)
231 throws ClassNotFoundException
232 {
233 if (type == null) throw new NullPointerException("type");
234
235
236 Class clazz = (Class) COMMON_TYPES.get(type);
237 if (clazz != null)
238 {
239 return clazz;
240 }
241
242 int len = type.length();
243 if (len > 2 && type.charAt(len - 1) == ']' && type.charAt(len - 2) == '[')
244 {
245 String componentType = type.substring(0, len - 2);
246 Class componentTypeClass = classForName(componentType);
247 return Array.newInstance(componentTypeClass, 0).getClass();
248 }
249
250 return classForName(type);
251
252 }
253
254
255
256
257
258
259
260
261
262
263 public static Class simpleJavaTypeToClass(String type)
264 {
265 try
266 {
267 return javaTypeToClass(type);
268 }
269 catch (ClassNotFoundException e)
270 {
271 log.log(Level.SEVERE, "Class " + type + " not found", e);
272 throw new FacesException(e);
273 }
274 }
275
276 public static URL getResource(String resource)
277 {
278 URL url = getContextClassLoader().getResource(resource);
279 if (url == null)
280 {
281 url = ClassUtils.class.getClassLoader().getResource(resource);
282 }
283 return url;
284 }
285
286 public static InputStream getResourceAsStream(String resource)
287 {
288 InputStream stream = getContextClassLoader()
289 .getResourceAsStream(resource);
290 if (stream == null)
291 {
292
293 stream = ClassUtils.class.getClassLoader().getResourceAsStream(resource);
294 }
295 return stream;
296 }
297
298
299
300
301
302
303 public static Iterator getResources(String resource, Object defaultObject)
304 {
305 try
306 {
307 Enumeration resources = getCurrentLoader(defaultObject).getResources(resource);
308 List lst = new ArrayList();
309 while (resources.hasMoreElements())
310 {
311 lst.add(resources.nextElement());
312 }
313 return lst.iterator();
314 }
315 catch (IOException e)
316 {
317 log.log(Level.SEVERE, e.getMessage(), e);
318 throw new FacesException(e);
319 }
320 }
321
322
323 public static Object newInstance(String type)
324 throws FacesException
325 {
326 if (type == null) return null;
327 return newInstance(simpleClassForName(type));
328 }
329
330 public static Object newInstance(String type, Class expectedType) throws FacesException
331 {
332 return newInstance(type, expectedType == null ? null : new Class[] {expectedType});
333 }
334
335 public static Object newInstance(String type, Class[] expectedTypes)
336 {
337 if (type == null)
338 return null;
339
340 Class clazzForName = simpleClassForName(type);
341
342 if(expectedTypes != null)
343 {
344 for (int i = 0, size = expectedTypes.length; i < size; i++)
345 {
346 if (!expectedTypes[i].isAssignableFrom(clazzForName))
347 {
348 throw new FacesException("'" + type + "' does not implement expected type '" + expectedTypes[i]
349 + "'");
350 }
351 }
352 }
353
354 return newInstance(clazzForName);
355 }
356
357 public static <T> T newInstance(Class<T> clazz)
358 throws FacesException
359 {
360 try
361 {
362 return clazz.newInstance();
363 }
364 catch(NoClassDefFoundError e)
365 {
366 log.log(Level.SEVERE, "Class : "+clazz.getName()+" not found.",e);
367 throw new FacesException(e);
368 }
369 catch (InstantiationException e)
370 {
371 log.log(Level.SEVERE, e.getMessage(), e);
372 throw new FacesException(e);
373 }
374 catch (IllegalAccessException e)
375 {
376 log.log(Level.SEVERE, e.getMessage(), e);
377 throw new FacesException(e);
378 }
379 }
380
381 public static <T> T newInstance(Class<T> clazz,
382 Class<?>[] constructorArgClasses,
383 Object... constructorArgs) throws NoSuchMethodException
384 {
385 if (constructorArgs.length == 0)
386 {
387
388 return newInstance(clazz);
389 }
390
391
392 Constructor constructor = clazz.getConstructor(constructorArgClasses);
393
394 try
395 {
396
397 return (T) constructor.newInstance(constructorArgs);
398 }
399 catch (Exception e)
400 {
401 throw new FacesException(e);
402 }
403 }
404
405 public static Object convertToType(Object value, Class desiredClass)
406 {
407 if (value == null) return null;
408
409 try
410 {
411 ExpressionFactory expFactory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
412 return expFactory.coerceToType(value, desiredClass);
413 }
414 catch (Exception e)
415 {
416 String message = "Cannot coerce " + value.getClass().getName()
417 + " to " + desiredClass.getName();
418 log.log(Level.SEVERE, message, e);
419 throw new FacesException(message, e);
420 }
421 }
422
423
424
425
426
427
428
429
430 protected static ClassLoader getCurrentLoader(Object defaultObject)
431 {
432 ClassLoader loader = getContextClassLoader();
433 if(loader == null)
434 {
435 loader = defaultObject.getClass().getClassLoader();
436 }
437 return loader;
438 }
439
440
441
442
443
444
445
446
447 public static ClassLoader getContextClassLoader()
448 {
449
450 return ClassLoaderUtils.getContextClassLoader();
451 }
452
453
454
455
456
457
458
459
460
461
462
463 public static <T> T buildApplicationObject(Class<T> interfaceClass, Collection<String> classNamesIterator, T defaultObject)
464 {
465 return buildApplicationObject(interfaceClass, null, null, classNamesIterator, defaultObject);
466 }
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483 @SuppressWarnings("unchecked")
484 public static <T> T buildApplicationObject(Class<T> interfaceClass, Class<? extends T> extendedInterfaceClass,
485 Class<? extends T> extendedInterfaceWrapperClass,
486 Collection<String> classNamesIterator, T defaultObject)
487 {
488 T current = defaultObject;
489
490
491 for (String implClassName : classNamesIterator)
492 {
493 Class<? extends T> implClass = ClassUtils.simpleClassForName(implClassName);
494
495
496 if (!interfaceClass.isAssignableFrom(implClass))
497 {
498 throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
499 }
500
501 if (current == null)
502 {
503
504 current = (T) ClassUtils.newInstance(implClass);
505 }
506 else
507 {
508
509 T newCurrent = null;
510 try
511 {
512 Constructor<? extends T> delegationConstructor = null;
513
514
515
516 if (extendedInterfaceClass != null
517 && extendedInterfaceClass.isAssignableFrom(current.getClass()))
518 {
519 try
520 {
521 delegationConstructor =
522 implClass.getConstructor(new Class[] {extendedInterfaceClass});
523 }
524 catch (NoSuchMethodException mnfe)
525 {
526
527 }
528 }
529 if (delegationConstructor == null)
530 {
531
532 delegationConstructor =
533 implClass.getConstructor(new Class[] {interfaceClass});
534 }
535
536 try
537 {
538
539 newCurrent = delegationConstructor.newInstance(new Object[] { current });
540 }
541 catch (InstantiationException e)
542 {
543 log.log(Level.SEVERE, e.getMessage(), e);
544 throw new FacesException(e);
545 }
546 catch (IllegalAccessException e)
547 {
548 log.log(Level.SEVERE, e.getMessage(), e);
549 throw new FacesException(e);
550 }
551 catch (InvocationTargetException e)
552 {
553 log.log(Level.SEVERE, e.getMessage(), e);
554 throw new FacesException(e);
555 }
556 }
557 catch (NoSuchMethodException e)
558 {
559
560 newCurrent = (T) ClassUtils.newInstance(implClass);
561 }
562
563
564
565
566 if (extendedInterfaceWrapperClass != null
567 && !extendedInterfaceClass.isAssignableFrom(newCurrent.getClass()))
568 {
569 try
570 {
571 Constructor<? extends T> wrapperConstructor
572 = extendedInterfaceWrapperClass.getConstructor(
573 new Class[] {interfaceClass, extendedInterfaceClass});
574 newCurrent = wrapperConstructor.newInstance(new Object[] {newCurrent, current});
575 }
576 catch (NoSuchMethodException e)
577 {
578 log.log(Level.SEVERE, e.getMessage(), e);
579 throw new FacesException(e);
580 }
581 catch (InstantiationException e)
582 {
583 log.log(Level.SEVERE, e.getMessage(), e);
584 throw new FacesException(e);
585 }
586 catch (IllegalAccessException e)
587 {
588 log.log(Level.SEVERE, e.getMessage(), e);
589 throw new FacesException(e);
590 }
591 catch (InvocationTargetException e)
592 {
593 log.log(Level.SEVERE, e.getMessage(), e);
594 throw new FacesException(e);
595 }
596 }
597
598 current = newCurrent;
599 }
600 }
601
602 return current;
603 }
604 }