1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util;
20
21 import java.lang.reflect.Constructor;
22 import java.lang.reflect.InvocationTargetException;
23
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25
26 @InterfaceAudience.Private
27 public class ReflectionUtils {
28 @SuppressWarnings("unchecked")
29 public static <T> T instantiateWithCustomCtor(String className,
30 Class<? >[] ctorArgTypes, Object[] ctorArgs) {
31 try {
32 Class<? extends T> resultType = (Class<? extends T>) Class.forName(className);
33 Constructor<? extends T> ctor = resultType.getDeclaredConstructor(ctorArgTypes);
34 return instantiate(className, ctor, ctorArgs);
35 } catch (ClassNotFoundException e) {
36 throw new UnsupportedOperationException(
37 "Unable to find " + className, e);
38 } catch (NoSuchMethodException e) {
39 throw new UnsupportedOperationException(
40 "Unable to find suitable constructor for class " + className, e);
41 }
42 }
43
44 private static <T> T instantiate(final String className, Constructor<T> ctor, Object[] ctorArgs) {
45 try {
46 return ctor.newInstance(ctorArgs);
47 } catch (IllegalAccessException e) {
48 throw new UnsupportedOperationException(
49 "Unable to access specified class " + className, e);
50 } catch (InstantiationException e) {
51 throw new UnsupportedOperationException(
52 "Unable to instantiate specified class " + className, e);
53 } catch (InvocationTargetException e) {
54 throw new UnsupportedOperationException(
55 "Constructor threw an exception for " + className, e);
56 }
57 }
58
59 @SuppressWarnings("unchecked")
60 public static <T> T newInstance(Class<T> type, Object... params) {
61 return instantiate(type.getName(), findConstructor(type, params), params);
62 }
63
64 @SuppressWarnings("unchecked")
65 public static <T> Constructor<T> findConstructor(Class<T> type, Object... paramTypes) {
66 Constructor<T>[] constructors = (Constructor<T>[])type.getConstructors();
67 for (Constructor<T> ctor : constructors) {
68 Class<?>[] ctorParamTypes = ctor.getParameterTypes();
69 if (ctorParamTypes.length != paramTypes.length) {
70 continue;
71 }
72
73 boolean match = true;
74 for (int i = 0; i < ctorParamTypes.length && match; ++i) {
75 Class<?> paramType = paramTypes[i].getClass();
76 match = (!ctorParamTypes[i].isPrimitive()) ? ctorParamTypes[i].isAssignableFrom(paramType) :
77 ((int.class.equals(ctorParamTypes[i]) && Integer.class.equals(paramType)) ||
78 (long.class.equals(ctorParamTypes[i]) && Long.class.equals(paramType)) ||
79 (char.class.equals(ctorParamTypes[i]) && Character.class.equals(paramType)) ||
80 (short.class.equals(ctorParamTypes[i]) && Short.class.equals(paramType)) ||
81 (boolean.class.equals(ctorParamTypes[i]) && Boolean.class.equals(paramType)) ||
82 (byte.class.equals(ctorParamTypes[i]) && Byte.class.equals(paramType)));
83 }
84
85 if (match) {
86 return ctor;
87 }
88 }
89 throw new UnsupportedOperationException(
90 "Unable to find suitable constructor for class " + type.getName());
91 }
92 }