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