001
014
015 package com.liferay.portal.kernel.test;
016
017 import com.liferay.portal.kernel.util.ReflectionUtil;
018
019 import java.lang.reflect.Constructor;
020 import java.lang.reflect.Field;
021 import java.lang.reflect.InvocationTargetException;
022 import java.lang.reflect.Method;
023
024 import java.util.Arrays;
025
026
029 public class ReflectionTestUtil {
030
031 public static Method getBridgeMethod(
032 Class<?> clazz, String methodName, Class<?>... parameterTypes) {
033
034 Method method = getMethod(clazz, methodName, parameterTypes);
035
036 if (method.isBridge()) {
037 return method;
038 }
039
040 Method bridgeMethod = _findBridgeMethod(clazz.getMethods(), method);
041
042 if (bridgeMethod != null) {
043 return bridgeMethod;
044 }
045
046 while (clazz != null) {
047 bridgeMethod = _findBridgeMethod(
048 clazz.getDeclaredMethods(), method);
049
050 if (bridgeMethod != null) {
051 return bridgeMethod;
052 }
053
054 clazz = clazz.getSuperclass();
055 }
056
057 return ReflectionUtil.throwException(
058 new NoSuchMethodException(
059 "No bridge method on " + clazz + " with name " + methodName +
060 " and parameter types " + Arrays.toString(parameterTypes)));
061 }
062
063 public static Field getField(Class<?> clazz, String fieldName) {
064 try {
065 Field field = clazz.getField(fieldName);
066
067 field.setAccessible(true);
068
069 ReflectionUtil.unfinalField(field);
070
071 return field;
072 }
073 catch (NoSuchFieldException nsfe) {
074 }
075 catch (Exception e) {
076 return ReflectionUtil.throwException(e);
077 }
078
079 while (clazz != null) {
080 try {
081 Field field = clazz.getDeclaredField(fieldName);
082
083 field.setAccessible(true);
084
085 ReflectionUtil.unfinalField(field);
086
087 return field;
088 }
089 catch (NoSuchFieldException nsfe) {
090 clazz = clazz.getSuperclass();
091 }
092 catch (Exception e) {
093 return ReflectionUtil.throwException(e);
094 }
095 }
096
097 return ReflectionUtil.throwException(
098 new NoSuchFieldException(
099 "No field on " + clazz + " with name " + fieldName));
100 }
101
102 public static <T> T getFieldValue(Class<?> clazz, String fieldName) {
103 Field field = getField(clazz, fieldName);
104
105 try {
106 return (T)field.get(null);
107 }
108 catch (Exception e) {
109 return ReflectionUtil.throwException(e);
110 }
111 }
112
113 public static <T> T getFieldValue(Object instance, String fieldName) {
114 Field field = getField(instance.getClass(), fieldName);
115
116 try {
117 return (T)field.get(instance);
118 }
119 catch (Exception e) {
120 return ReflectionUtil.throwException(e);
121 }
122 }
123
124 public static Method getMethod(
125 Class<?> clazz, String methodName, Class<?>... parameterTypes) {
126
127 try {
128 Method method = clazz.getMethod(methodName, parameterTypes);
129
130 method.setAccessible(true);
131
132 return method;
133 }
134 catch (NoSuchMethodException nsme) {
135 }
136
137 while (clazz != null) {
138 try {
139 Method method = clazz.getDeclaredMethod(
140 methodName, parameterTypes);
141
142 method.setAccessible(true);
143
144 return method;
145 }
146 catch (NoSuchMethodException nsme) {
147 clazz = clazz.getSuperclass();
148 }
149 }
150
151 return ReflectionUtil.throwException(
152 new NoSuchMethodException(
153 "No method on " + clazz + " with name " + methodName +
154 " and parameter types " + Arrays.toString(parameterTypes)));
155 }
156
157 public static <T> T invoke(
158 Class<?> clazz, String methodName, Class<?>[] parameterTypes,
159 Object... parameters) {
160
161 Method method = getMethod(clazz, methodName, parameterTypes);
162
163 try {
164 return (T)method.invoke(null, parameters);
165 }
166 catch (InvocationTargetException ite) {
167 return ReflectionUtil.throwException(ite.getCause());
168 }
169 catch (Exception e) {
170 return ReflectionUtil.throwException(e);
171 }
172 }
173
174 public static <T> T invoke(
175 Object instance, String methodName, Class<?>[] parameterTypes,
176 Object... parameters) {
177
178 Method method = getMethod(
179 instance.getClass(), methodName, parameterTypes);
180
181 try {
182 return (T)method.invoke(instance, parameters);
183 }
184 catch (InvocationTargetException ite) {
185 return ReflectionUtil.throwException(ite.getCause());
186 }
187 catch (Exception e) {
188 return ReflectionUtil.throwException(e);
189 }
190 }
191
192 public static <T> T invokeBridge(
193 Object instance, String methodName, Class<?>[] parameterTypes,
194 Object... parameters) {
195
196 Method method = getBridgeMethod(
197 instance.getClass(), methodName, parameterTypes);
198
199 try {
200 return (T)method.invoke(instance, parameters);
201 }
202 catch (InvocationTargetException ite) {
203 return ReflectionUtil.throwException(ite.getCause());
204 }
205 catch (Exception e) {
206 return ReflectionUtil.throwException(e);
207 }
208 }
209
210 public static <T extends Enum<T>> T newEnumElement(
211 Class<T> enumClass, Class<?>[] constructorParameterTypes, String name,
212 int ordinal, Object... constructorParameters) {
213
214 Class<?>[] parameterTypes = null;
215
216 if ((constructorParameterTypes != null) &&
217 (constructorParameterTypes.length != 0)) {
218
219 parameterTypes = new Class<?>[constructorParameterTypes.length + 2];
220
221 parameterTypes[0] = String.class;
222 parameterTypes[1] = int.class;
223
224 System.arraycopy(
225 constructorParameterTypes, 0, parameterTypes, 2,
226 constructorParameterTypes.length);
227 }
228 else {
229 parameterTypes = new Class<?>[2];
230
231 parameterTypes[0] = String.class;
232 parameterTypes[1] = int.class;
233 }
234
235 try {
236 Constructor<T> constructor = enumClass.getDeclaredConstructor(
237 parameterTypes);
238
239 Method acquireConstructorAccessorMethod =
240 ReflectionUtil.getDeclaredMethod(
241 Constructor.class, "acquireConstructorAccessor");
242
243 acquireConstructorAccessorMethod.invoke(constructor);
244
245 Field constructorAccessorField = ReflectionUtil.getDeclaredField(
246 Constructor.class, "constructorAccessor");
247
248 Object constructorAccessor = constructorAccessorField.get(
249 constructor);
250
251 Method newInstanceMethod = ReflectionUtil.getDeclaredMethod(
252 constructorAccessor.getClass(), "newInstance", Object[].class);
253
254 Object[] parameters = null;
255
256 if ((constructorParameters != null) &&
257 (constructorParameters.length != 0)) {
258
259 parameters = new Object[constructorParameters.length + 2];
260
261 parameters[0] = name;
262 parameters[1] = ordinal;
263
264 System.arraycopy(
265 constructorParameters, 0, parameters, 2,
266 constructorParameters.length);
267 }
268 else {
269 parameters = new Object[2];
270
271 parameters[0] = name;
272 parameters[1] = ordinal;
273 }
274
275 return (T)newInstanceMethod.invoke(
276 constructorAccessor, new Object[] {parameters});
277 }
278 catch (Exception e) {
279 return ReflectionUtil.throwException(e);
280 }
281 }
282
283 public static <T extends Enum<T>> T newEnumElement(
284 Class<T> enumClass, String name, int ordinal) {
285
286 return newEnumElement(enumClass, null, name, ordinal, (Object[])null);
287 }
288
289 public static void setFieldValue(
290 Class<?> clazz, String fieldName, Object value) {
291
292 Field field = getField(clazz, fieldName);
293
294 try {
295 field.set(null, value);
296 }
297 catch (Exception e) {
298 ReflectionUtil.throwException(e);
299 }
300 }
301
302 public static void setFieldValue(
303 Object instance, String fieldName, Object value) {
304
305 Field field = getField(instance.getClass(), fieldName);
306
307 try {
308 field.set(instance, value);
309 }
310 catch (Exception e) {
311 ReflectionUtil.throwException(e);
312 }
313 }
314
315 private static Method _findBridgeMethod(Method[] methods, Method method) {
316 String name = method.getName();
317 Class<?>[] parameterTypes = method.getParameterTypes();
318
319 bridge:
320 for (Method currentMethod : methods) {
321 if (!currentMethod.isBridge() ||
322 !name.equals(currentMethod.getName())) {
323
324 continue;
325 }
326
327 Class<?>[] currentParameterTypes =
328 currentMethod.getParameterTypes();
329
330 if (currentParameterTypes.length != parameterTypes.length) {
331 continue;
332 }
333
334 for (int i = 0; i < currentParameterTypes.length; i++) {
335 if (!currentParameterTypes[i].isAssignableFrom(
336 parameterTypes[i])) {
337
338 continue bridge;
339 }
340 }
341
342 currentMethod.setAccessible(true);
343
344 return currentMethod;
345 }
346
347 return null;
348 }
349
350 }