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