1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.hivemind.util; |
16 |
| |
17 |
| import java.lang.reflect.Constructor; |
18 |
| import java.lang.reflect.InvocationTargetException; |
19 |
| import java.lang.reflect.Modifier; |
20 |
| import java.util.ArrayList; |
21 |
| import java.util.HashMap; |
22 |
| import java.util.List; |
23 |
| import java.util.Map; |
24 |
| |
25 |
| import org.apache.hivemind.ApplicationRuntimeException; |
26 |
| |
27 |
| |
28 |
| |
29 |
| |
30 |
| |
31 |
| |
32 |
| public class ConstructorUtils |
33 |
| { |
34 |
| |
35 |
| |
36 |
| |
37 |
| |
38 |
| private static final Map _primitiveMap = new HashMap(); |
39 |
| |
40 |
| static |
41 |
| { |
42 |
1
| _primitiveMap.put(boolean.class, Boolean.class);
|
43 |
1
| _primitiveMap.put(byte.class, Byte.class);
|
44 |
1
| _primitiveMap.put(char.class, Character.class);
|
45 |
1
| _primitiveMap.put(short.class, Short.class);
|
46 |
1
| _primitiveMap.put(int.class, Integer.class);
|
47 |
1
| _primitiveMap.put(long.class, Long.class);
|
48 |
1
| _primitiveMap.put(float.class, Float.class);
|
49 |
1
| _primitiveMap.put(double.class, Double.class);
|
50 |
| } |
51 |
| |
52 |
| |
53 |
| |
54 |
0
| private ConstructorUtils()
|
55 |
| { |
56 |
| } |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
44
| public static Object invokeConstructor(Class targetClass, Object[] parameters)
|
70 |
| { |
71 |
44
| if (parameters == null)
|
72 |
0
| parameters = new Object[0];
|
73 |
| |
74 |
44
| Class[] parameterTypes = new Class[parameters.length];
|
75 |
| |
76 |
44
| for (int i = 0; i < parameters.length; i++)
|
77 |
44
| parameterTypes[i] = parameters[i] == null ? null : parameters[i].getClass();
|
78 |
| |
79 |
44
| return invokeMatchingConstructor(targetClass, parameterTypes, parameters);
|
80 |
| } |
81 |
| |
82 |
44
| private static Object invokeMatchingConstructor(Class targetClass, Class[] parameterTypes,
|
83 |
| Object[] parameters) |
84 |
| { |
85 |
44
| Constructor[] constructors = targetClass.getConstructors();
|
86 |
| |
87 |
44
| for (int i = 0; i < constructors.length; i++)
|
88 |
| { |
89 |
44
| Constructor c = constructors[i];
|
90 |
| |
91 |
44
| if (isMatch(c, parameterTypes))
|
92 |
44
| return invoke(c, parameters);
|
93 |
| } |
94 |
| |
95 |
0
| throw new ApplicationRuntimeException(UtilMessages.noMatchingConstructor(targetClass), null);
|
96 |
| } |
97 |
| |
98 |
44
| private static boolean isMatch(Constructor c, Class[] types)
|
99 |
| { |
100 |
44
| Class[] actualTypes = c.getParameterTypes();
|
101 |
| |
102 |
44
| if (actualTypes.length != types.length)
|
103 |
0
| return false;
|
104 |
| |
105 |
44
| for (int i = 0; i < types.length; i++)
|
106 |
| { |
107 |
44
| if (types[i] == null && !actualTypes[i].isPrimitive())
|
108 |
0
| continue;
|
109 |
| |
110 |
44
| if (!isCompatible(actualTypes[i], types[i]))
|
111 |
0
| return false;
|
112 |
| } |
113 |
| |
114 |
44
| return true;
|
115 |
| } |
116 |
| |
117 |
63
| public static boolean isCompatible(Class actualType, Class parameterType)
|
118 |
| { |
119 |
63
| if (actualType.isAssignableFrom(parameterType))
|
120 |
50
| return true;
|
121 |
| |
122 |
| |
123 |
| |
124 |
| |
125 |
13
| if (actualType.isPrimitive())
|
126 |
| { |
127 |
6
| Class wrapperClass = (Class) _primitiveMap.get(actualType);
|
128 |
| |
129 |
6
| return wrapperClass.isAssignableFrom(parameterType);
|
130 |
| } |
131 |
| |
132 |
7
| return false;
|
133 |
| } |
134 |
| |
135 |
833
| public static Object invoke(Constructor c, Object[] parameters)
|
136 |
| { |
137 |
833
| try
|
138 |
| { |
139 |
833
| return c.newInstance(parameters);
|
140 |
| } |
141 |
| catch (InvocationTargetException ex) |
142 |
| { |
143 |
1
| Throwable cause = ex.getTargetException();
|
144 |
| |
145 |
1
| throw new ApplicationRuntimeException(UtilMessages.invokeFailed(c, cause), null, cause);
|
146 |
| } |
147 |
| catch (Exception ex) |
148 |
| { |
149 |
0
| throw new ApplicationRuntimeException(UtilMessages.invokeFailed(c, ex), null, ex);
|
150 |
| } |
151 |
| } |
152 |
| |
153 |
0
| public static List getConstructorsOfLength(final Class clazz, final int length)
|
154 |
| { |
155 |
0
| List fixedLengthConstructors = new ArrayList(1);
|
156 |
| |
157 |
0
| Constructor[] constructors = clazz.getDeclaredConstructors();
|
158 |
| |
159 |
0
| outer: for (int i = 0; i < constructors.length; i++)
|
160 |
| { |
161 |
0
| if (!Modifier.isPublic(constructors[i].getModifiers()))
|
162 |
0
| continue;
|
163 |
| |
164 |
0
| Class[] parameterTypes = constructors[i].getParameterTypes();
|
165 |
| |
166 |
0
| if (parameterTypes.length == length)
|
167 |
0
| fixedLengthConstructors.add(constructors[i]);
|
168 |
| } |
169 |
| |
170 |
0
| return fixedLengthConstructors;
|
171 |
| } |
172 |
| } |