1
2
3
4
5
6
7
8
9
10
11 package org.mule.util;
12
13 import org.mule.routing.filters.WildcardFilter;
14
15 import java.io.BufferedReader;
16 import java.io.CharArrayReader;
17 import java.io.IOException;
18 import java.io.Reader;
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Modifier;
23 import java.net.URL;
24 import java.security.AccessController;
25 import java.security.PrivilegedAction;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.Enumeration;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34
35
36
37
38
39
40
41
42
43 public class ClassUtils extends org.apache.commons.lang.ClassUtils
44 {
45 public static final Object[] NO_ARGS = new Object[]{};
46 public static final Class[] NO_ARGS_TYPE = new Class[]{};
47
48 private static final Map wrapperToPrimitiveMap = new HashMap();
49
50 static
51 {
52 wrapperToPrimitiveMap.put(Boolean.class, Boolean.TYPE);
53 wrapperToPrimitiveMap.put(Byte.class, Byte.TYPE);
54 wrapperToPrimitiveMap.put(Character.class, Character.TYPE);
55 wrapperToPrimitiveMap.put(Short.class, Short.TYPE);
56 wrapperToPrimitiveMap.put(Integer.class, Integer.TYPE);
57 wrapperToPrimitiveMap.put(Long.class, Long.TYPE);
58 wrapperToPrimitiveMap.put(Double.class, Double.TYPE);
59 wrapperToPrimitiveMap.put(Float.class, Float.TYPE);
60 wrapperToPrimitiveMap.put(Void.TYPE, Void.TYPE);
61 }
62
63 public static boolean isConcrete(Class clazz)
64 {
65 if (clazz == null)
66 {
67 throw new IllegalArgumentException("clazz may not be null");
68 }
69 return !(clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()));
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public static URL getResource(final String resourceName, final Class callingClass)
87 {
88 URL url = (URL) AccessController.doPrivileged(new PrivilegedAction()
89 {
90 public Object run()
91 {
92 final ClassLoader cl = Thread.currentThread().getContextClassLoader();
93 return cl != null ? cl.getResource(resourceName) : null;
94 }
95 });
96
97 if (url == null)
98 {
99 url = (URL) AccessController.doPrivileged(new PrivilegedAction()
100 {
101 public Object run()
102 {
103 return ClassUtils.class.getClassLoader().getResource(resourceName);
104 }
105 });
106 }
107
108 if (url == null)
109 {
110 url = (URL) AccessController.doPrivileged(new PrivilegedAction()
111 {
112 public Object run()
113 {
114 return callingClass.getClassLoader().getResource(resourceName);
115 }
116 });
117 }
118
119 return url;
120 }
121
122 public static Enumeration getResources(final String resourceName, final Class callingClass)
123 {
124 Enumeration enumeration = (Enumeration) AccessController.doPrivileged(new PrivilegedAction()
125 {
126 public Object run()
127 {
128 try
129 {
130 final ClassLoader cl = Thread.currentThread().getContextClassLoader();
131 return cl != null ? cl.getResources(resourceName) : null;
132 }
133 catch (IOException e)
134 {
135 return null;
136 }
137 }
138 });
139
140 if (enumeration == null)
141 {
142 enumeration = (Enumeration) AccessController.doPrivileged(new PrivilegedAction()
143 {
144 public Object run()
145 {
146 try
147 {
148 return ClassUtils.class.getClassLoader().getResources(resourceName);
149 }
150 catch (IOException e)
151 {
152 return null;
153 }
154 }
155 });
156 }
157
158 if (enumeration == null)
159 {
160 enumeration = (Enumeration) AccessController.doPrivileged(new PrivilegedAction()
161 {
162 public Object run()
163 {
164 try
165 {
166 return callingClass.getClassLoader().getResources(resourceName);
167 }
168 catch (IOException e)
169 {
170 return null;
171 }
172 }
173 });
174 }
175
176 return enumeration;
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 public static Class loadClass(final String className, final Class callingClass)
196 throws ClassNotFoundException
197 {
198 Class clazz = (Class) AccessController.doPrivileged(new PrivilegedAction()
199 {
200 public Object run()
201 {
202 try
203 {
204 final ClassLoader cl = Thread.currentThread().getContextClassLoader();
205 return cl != null ? cl.loadClass(className) : null;
206
207 }
208 catch (ClassNotFoundException e)
209 {
210 return null;
211 }
212 }
213 });
214
215 if (clazz == null)
216 {
217 clazz = (Class) AccessController.doPrivileged(new PrivilegedAction()
218 {
219 public Object run()
220 {
221 try
222 {
223 return Class.forName(className);
224 }
225 catch (ClassNotFoundException e)
226 {
227 return null;
228 }
229 }
230 });
231 }
232
233 if (clazz == null)
234 {
235 clazz = (Class) AccessController.doPrivileged(new PrivilegedAction()
236 {
237 public Object run()
238 {
239 try
240 {
241 return ClassUtils.class.getClassLoader().loadClass(className);
242 }
243 catch (ClassNotFoundException e)
244 {
245 return null;
246 }
247 }
248 });
249 }
250
251 if (clazz == null)
252 {
253 clazz = (Class) AccessController.doPrivileged(new PrivilegedAction()
254 {
255 public Object run()
256 {
257 try
258 {
259 return callingClass.getClassLoader().loadClass(className);
260 }
261 catch (ClassNotFoundException e)
262 {
263 return null;
264 }
265 }
266 });
267 }
268
269 if (clazz == null)
270 {
271 throw new ClassNotFoundException(className);
272 }
273
274 return clazz;
275 }
276
277
278 public static void printClassLoader()
279 {
280 System.out.println("ClassLoaderUtils.printClassLoader");
281 printClassLoader(Thread.currentThread().getContextClassLoader());
282 }
283
284
285
286
287
288 public static void printClassLoader(ClassLoader cl)
289 {
290 System.out.println("ClassLoaderUtils.printClassLoader(cl = " + cl + ")");
291
292 if (cl != null)
293 {
294 printClassLoader(cl.getParent());
295 }
296 }
297
298
299
300
301
302
303
304
305
306 public static Class initializeClass(Class clazz)
307 {
308 try
309 {
310 return getClass(clazz.getName(), true);
311 }
312 catch (ClassNotFoundException e)
313 {
314 IllegalStateException ise = new IllegalStateException();
315 ise.initCause(e);
316 throw ise;
317 }
318 }
319
320 public static Object instanciateClass(Class clazz, Object[] constructorArgs)
321 throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException,
322 IllegalAccessException, InvocationTargetException
323 {
324 Class[] args;
325 if (constructorArgs != null)
326 {
327 args = new Class[constructorArgs.length];
328 for (int i = 0; i < constructorArgs.length; i++)
329 {
330 if (constructorArgs[i] == null)
331 {
332 args[i] = null;
333 }
334 else
335 {
336 args[i] = constructorArgs[i].getClass();
337 }
338 }
339 }
340 else
341 {
342 args = new Class[0];
343 }
344
345
346 Constructor ctor = getConstructor(clazz, args);
347
348 if (ctor == null)
349 {
350
351 ctor = getConstructor(clazz, wrappersToPrimitives(args));
352 }
353
354 if (ctor == null)
355 {
356 StringBuffer argsString = new StringBuffer(100);
357 for (int i = 0; i < args.length; i++)
358 {
359 argsString.append(args[i].getName()).append(", ");
360 }
361 throw new NoSuchMethodException("could not find constructor with matching arg params: "
362 + argsString);
363 }
364
365 return ctor.newInstance(constructorArgs);
366 }
367
368 public static Object instanciateClass(String name, Object[] constructorArgs)
369 throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException,
370 InstantiationException, IllegalAccessException, InvocationTargetException
371 {
372 Class clazz = loadClass(name, ClassUtils.class);
373 return instanciateClass(clazz, constructorArgs);
374
375 }
376
377 public static Object instanciateClass(String name, Object[] constructorArgs, Class callingClass)
378 throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException,
379 InstantiationException, IllegalAccessException, InvocationTargetException
380 {
381 Class clazz = loadClass(name, callingClass);
382 return instanciateClass(clazz, constructorArgs);
383 }
384
385 public static Class[] getParameterTypes(Object bean, String methodName)
386 {
387 if (!methodName.startsWith("set"))
388 {
389 methodName = "set" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
390 }
391
392 Method methods[] = bean.getClass().getMethods();
393
394 for (int i = 0; i < methods.length; i++)
395 {
396 if (methods[i].getName().equals(methodName))
397 {
398 return methods[i].getParameterTypes();
399 }
400 }
401
402 return new Class[]{};
403 }
404
405
406
407
408
409
410
411
412
413
414
415 public static Method getMethod(Class clazz, String name, Class[] parameterTypes)
416 {
417 Method[] methods = clazz.getMethods();
418 for (int i = 0; i < methods.length; i++)
419 {
420 if (methods[i].getName().equals(name))
421 {
422 if (parameterTypes == null)
423 {
424 return methods[i];
425 }
426 else if (compare(methods[i].getParameterTypes(), parameterTypes, true))
427 {
428 return methods[i];
429 }
430 }
431 }
432 return null;
433 }
434
435 public static Constructor getConstructor(Class clazz, Class[] paramTypes)
436 {
437 Constructor[] ctors = clazz.getConstructors();
438 for (int i = 0; i < ctors.length; i++)
439 {
440 Class[] types = ctors[i].getParameterTypes();
441 if (types.length == paramTypes.length)
442 {
443 boolean match = true;
444 for (int x = 0; x < types.length; x++)
445 {
446 if (paramTypes[x] == null)
447 {
448 match = true;
449 }
450 else
451 {
452 match = types[x].isAssignableFrom(paramTypes[x]);
453 }
454 }
455 if (match)
456 {
457 return ctors[i];
458 }
459 }
460 }
461 return null;
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 public static List getSatisfiableMethods(Class implementation,
479 Class[] parameterTypes,
480 boolean voidOk,
481 boolean matchOnObject,
482 Set ignoredMethodNames)
483 {
484 return getSatisfiableMethods(implementation, parameterTypes, voidOk, matchOnObject, ignoredMethodNames, null);
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501 public static List getSatisfiableMethods(Class implementation,
502 Class[] parameterTypes,
503 boolean voidOk,
504 boolean matchOnObject,
505 Collection ignoredMethodNames,
506 WildcardFilter filter)
507 {
508
509
510 List result = new ArrayList();
511
512 if (ignoredMethodNames == null)
513 {
514 ignoredMethodNames = Collections.EMPTY_SET;
515 }
516
517 Method[] methods = implementation.getMethods();
518 for (int i = 0; i < methods.length; i++)
519 {
520 Method method = methods[i];
521
522 if (filter != null && filter.accept(method.getName()))
523 {
524 continue;
525 }
526 Class[] methodParams = method.getParameterTypes();
527
528 if (compare(methodParams, parameterTypes, matchOnObject))
529 {
530 if (!ignoredMethodNames.contains(method.getName()))
531 {
532 String returnType = method.getReturnType().getName();
533 if ((returnType.equals("void") && voidOk) || !returnType.equals("void"))
534 {
535 result.add(method);
536 }
537 }
538 }
539 }
540
541 return result;
542 }
543
544 public static List getSatisfiableMethodsWithReturnType(Class implementation,
545 Class returnType,
546 boolean matchOnObject,
547 Set ignoredMethodNames)
548 {
549 List result = new ArrayList();
550
551 if (ignoredMethodNames == null)
552 {
553 ignoredMethodNames = Collections.EMPTY_SET;
554 }
555
556 Method[] methods = implementation.getMethods();
557 for (int i = 0; i < methods.length; i++)
558 {
559 Method method = methods[i];
560 Class returns = method.getReturnType();
561
562 if (compare(new Class[]{returns}, new Class[]{returnType}, matchOnObject))
563 {
564 if (!ignoredMethodNames.contains(method.getName()))
565 {
566 result.add(method);
567 }
568 }
569 }
570
571 return result;
572 }
573
574
575
576
577
578
579
580
581
582 public static boolean isClassOnPath(String className, Class currentClass)
583 {
584 try
585 {
586 return (loadClass(className, currentClass) != null);
587 }
588 catch (ClassNotFoundException e)
589 {
590 return false;
591 }
592 }
593
594
595
596
597
598
599
600
601 public static Class[] getClassTypes(Object object)
602 {
603 if (object == null)
604 {
605 return NO_ARGS_TYPE;
606 }
607
608 Class[] types;
609
610 if (object instanceof Object[])
611 {
612 Object[] objects = (Object[]) object;
613 if (objects.length == 0)
614 {
615 return NO_ARGS_TYPE;
616 }
617 types = new Class[objects.length];
618 for (int i = 0; i < objects.length; i++)
619 {
620 types[i] = objects[i].getClass();
621 }
622 }
623 else
624 {
625 types = new Class[]{object.getClass()};
626 }
627
628 return types;
629 }
630
631 public static String getClassName(Class clazz)
632 {
633 if (clazz == null)
634 {
635 return null;
636 }
637 String name = clazz.getName();
638 return name.substring(name.lastIndexOf(".") + 1);
639 }
640
641 public static boolean compare(Class[] c1, Class[] c2, boolean matchOnObject)
642 {
643 if (c1.length != c2.length)
644 {
645 return false;
646 }
647 for (int i = 0; i < c1.length; i++)
648 {
649 if (c1[i].equals(Object.class) && !matchOnObject)
650 {
651 return false;
652 }
653 if (!c1[i].isAssignableFrom(c2[i]))
654 {
655
656 return false;
657 }
658 }
659 return true;
660 }
661
662 public static Class wrapperToPrimitive(Class wrapper)
663 {
664 return (Class) MapUtils.getObject(wrapperToPrimitiveMap, wrapper, wrapper);
665 }
666
667 public static Class[] wrappersToPrimitives(Class[] wrappers)
668 {
669 if (wrappers == null)
670 {
671 return null;
672 }
673
674 if (wrappers.length == 0)
675 {
676 return wrappers;
677 }
678
679 Class[] primitives = new Class[wrappers.length];
680
681 for (int i = 0; i < wrappers.length; i++)
682 {
683 primitives[i] = (Class) MapUtils.getObject(wrapperToPrimitiveMap, wrappers[i], wrappers[i]);
684 }
685
686 return primitives;
687 }
688
689
690
691
692
693
694
695 public static String getSimpleName(Class clazz)
696 {
697 if (null == clazz)
698 {
699 return "null";
700 }
701 else
702 {
703 return classNameHelper(new BufferedReader(new CharArrayReader(clazz.getName().toCharArray())));
704 }
705 }
706
707 private static String classNameHelper(Reader encodedName)
708 {
709
710
711
712
713 try
714 {
715 encodedName.mark(1);
716 switch (encodedName.read())
717 {
718 case -1:
719 return "null";
720 case 'Z':
721 return "boolean";
722 case 'B':
723 return "byte";
724 case 'C':
725 return "char";
726 case 'D':
727 return "double";
728 case 'F':
729 return "float";
730 case 'I':
731 return "int";
732 case 'J':
733 return "long";
734 case 'S':
735 return "short";
736 case '[':
737 return classNameHelper(encodedName) + "[]";
738 case 'L':
739 return shorten(new BufferedReader(encodedName).readLine());
740 default:
741 encodedName.reset();
742 return shorten(new BufferedReader(encodedName).readLine());
743 }
744 }
745 catch (IOException e)
746 {
747 return "unknown type: " + e.getMessage();
748 }
749 }
750
751
752
753
754
755 private static String shorten(String clazz)
756 {
757 if (null != clazz && clazz.endsWith(";"))
758 {
759 clazz = clazz.substring(0, clazz.length() - 1);
760 }
761 if (null != clazz && clazz.lastIndexOf(".") > -1)
762 {
763 clazz = clazz.substring(clazz.lastIndexOf(".") + 1, clazz.length());
764 }
765 return clazz;
766 }
767
768
769
770
771 public static boolean equal(Object a, Object b)
772 {
773 if (null == a)
774 {
775 return null == b;
776 }
777 else
778 {
779 return null != b && a.equals(b);
780 }
781 }
782
783 public static int hash(Object[] state)
784 {
785 int hash = 0;
786 for (int i = 0; i < state.length; ++i)
787 {
788 hash = hash * 31 + (null == state[i] ? 0 : state[i].hashCode());
789 }
790 return hash;
791 }
792
793 }