001
014
015 package com.liferay.portal.kernel.util;
016
017 import java.lang.annotation.Annotation;
018 import java.lang.reflect.Constructor;
019 import java.lang.reflect.Field;
020 import java.lang.reflect.Method;
021
022 import java.util.Arrays;
023 import java.util.List;
024
025
030 public class ReflectionUtil {
031
032 public static Class<?> getAnnotationDeclaringClass(
033 Class<? extends Annotation> annotationClass, Class<?> clazz) {
034
035 if ((clazz == null) || clazz.equals(Object.class)) {
036 return null;
037 }
038
039 if (isAnnotationDeclaredInClass(annotationClass, clazz)) {
040 return clazz;
041 }
042 else {
043 return getAnnotationDeclaringClass(
044 annotationClass, clazz.getSuperclass());
045 }
046 }
047
048 public static Method getBridgeMethod(
049 Class<?> clazz, String name, Class<?> ... parameterTypes)
050 throws Exception {
051
052 Method method = clazz.getMethod(name, parameterTypes);
053
054 if (method.isBridge()) {
055 return method;
056 }
057
058 bridge:
059 for (Method currentMethod : clazz.getMethods()) {
060 if (!currentMethod.isBridge() ||
061 name.equals(currentMethod.getName())) {
062
063 continue;
064 }
065
066 Class<?>[] currentParameterTypes =
067 currentMethod.getParameterTypes();
068
069 if (currentParameterTypes.length != parameterTypes.length) {
070 continue;
071 }
072
073 for (int i = 0; i < currentParameterTypes.length; i++) {
074 if (!currentParameterTypes[i].isAssignableFrom(
075 parameterTypes[i])) {
076
077 continue bridge;
078 }
079 }
080
081 return currentMethod;
082 }
083
084 throw new NoSuchMethodException(
085 "No bridge method on " + clazz + " with name " + name +
086 " and parameter types " + Arrays.toString(parameterTypes));
087 }
088
089 public static Field getDeclaredField(Class<?> clazz, String name)
090 throws Exception {
091
092 Field field = clazz.getDeclaredField(name);
093
094 if (!field.isAccessible()) {
095 field.setAccessible(true);
096 }
097
098 return field;
099 }
100
101 public static Method getDeclaredMethod(
102 Class<?> clazz, String name, Class<?> ... parameterTypes)
103 throws Exception {
104
105 Method method = clazz.getDeclaredMethod(name, parameterTypes);
106
107 if (!method.isAccessible()) {
108 method.setAccessible(true);
109 }
110
111 return method;
112 }
113
114 public static Class<?>[] getInterfaces(Object object) {
115 return getInterfaces(object, null);
116 }
117
118 public static Class<?>[] getInterfaces(
119 Object object, ClassLoader classLoader) {
120
121 List<Class<?>> interfaceClasses = new UniqueList<Class<?>>();
122
123 Class<?> clazz = object.getClass();
124
125 _getInterfaces(interfaceClasses, clazz, classLoader);
126
127 Class<?> superClass = clazz.getSuperclass();
128
129 while (superClass != null) {
130 _getInterfaces(interfaceClasses, superClass, classLoader);
131
132 superClass = superClass.getSuperclass();
133 }
134
135 return interfaceClasses.toArray(new Class<?>[interfaceClasses.size()]);
136 }
137
138 public static Class<?>[] getParameterTypes(Object[] arguments) {
139 if (arguments == null) {
140 return null;
141 }
142
143 Class<?>[] parameterTypes = new Class<?>[arguments.length];
144
145 for (int i = 0; i < arguments.length; i++) {
146 if (arguments[i] == null) {
147 parameterTypes[i] = null;
148 }
149 else if (arguments[i] instanceof Boolean) {
150 parameterTypes[i] = Boolean.TYPE;
151 }
152 else if (arguments[i] instanceof Byte) {
153 parameterTypes[i] = Byte.TYPE;
154 }
155 else if (arguments[i] instanceof Character) {
156 parameterTypes[i] = Character.TYPE;
157 }
158 else if (arguments[i] instanceof Double) {
159 parameterTypes[i] = Double.TYPE;
160 }
161 else if (arguments[i] instanceof Float) {
162 parameterTypes[i] = Float.TYPE;
163 }
164 else if (arguments[i] instanceof Integer) {
165 parameterTypes[i] = Integer.TYPE;
166 }
167 else if (arguments[i] instanceof Long) {
168 parameterTypes[i] = Long.TYPE;
169 }
170 else if (arguments[i] instanceof Short) {
171 parameterTypes[i] = Short.TYPE;
172 }
173 else {
174 parameterTypes[i] = arguments[i].getClass();
175 }
176 }
177
178 return parameterTypes;
179 }
180
181 public static boolean isAnnotationDeclaredInClass(
182 Class<? extends Annotation> annotationClass, Class<?> clazz) {
183
184 if ((annotationClass == null) || (clazz == null)) {
185 throw new IllegalArgumentException();
186 }
187
188 Annotation[] annotations = clazz.getAnnotations();
189
190 for (Annotation annotation : annotations) {
191 if (annotationClass.equals(annotation.annotationType())) {
192 return true;
193 }
194 }
195
196 return false;
197 }
198
199 public static <T extends Enum<T>> T newEnumElement(
200 Class<T> enumClass, Class<?>[] constructorParameterTypes,
201 String name, int ordinal, Object... constructorParameters)
202 throws Exception {
203
204 Class<?>[] parameterTypes = null;
205
206 if ((constructorParameterTypes != null) &&
207 (constructorParameterTypes.length != 0)) {
208
209 parameterTypes = new Class<?>[constructorParameterTypes.length + 2];
210
211 parameterTypes[0] = String.class;
212 parameterTypes[1] = int.class;
213
214 System.arraycopy(
215 constructorParameterTypes, 0, parameterTypes, 2,
216 constructorParameterTypes.length);
217 }
218 else {
219 parameterTypes = new Class<?>[2];
220
221 parameterTypes[0] = String.class;
222 parameterTypes[1] = int.class;
223 }
224
225 Constructor<T> constructor = enumClass.getDeclaredConstructor(
226 parameterTypes);
227
228 Method acquireConstructorAccessorMethod = getDeclaredMethod(
229 Constructor.class, "acquireConstructorAccessor");
230
231 acquireConstructorAccessorMethod.invoke(constructor);
232
233 Field constructorAccessorField = getDeclaredField(
234 Constructor.class, "constructorAccessor");
235
236 Object constructorAccessor = constructorAccessorField.get(constructor);
237
238 Method newInstanceMethod = getDeclaredMethod(
239 constructorAccessor.getClass(), "newInstance", Object[].class);
240
241 Object[] parameters = null;
242
243 if ((constructorParameters != null) &&
244 (constructorParameters.length != 0)) {
245
246 parameters = new Object[constructorParameters.length + 2];
247
248 parameters[0] = name;
249 parameters[1] = ordinal;
250
251 System.arraycopy(
252 constructorParameters, 0, parameters, 2,
253 constructorParameters.length);
254
255 }
256 else {
257 parameters = new Object[2];
258
259 parameters[0] = name;
260 parameters[1] = ordinal;
261 }
262
263 return (T)newInstanceMethod.invoke(
264 constructorAccessor, new Object[]{parameters});
265 }
266
267 public static <T extends Enum<T>> T newEnumElement(
268 Class<T> enumClass, String name, int ordinal)
269 throws Exception {
270
271 return newEnumElement(enumClass, null, name, ordinal, (Object[])null);
272 }
273
274 private static void _getInterfaces(
275 List<Class<?>> interfaceClasses, Class<?> clazz,
276 ClassLoader classLoader) {
277
278 for (Class<?> interfaceClass : clazz.getInterfaces()) {
279 try {
280 if (classLoader != null) {
281 interfaceClasses.add(
282 classLoader.loadClass(interfaceClass.getName()));
283 }
284 else {
285 interfaceClasses.add(interfaceClass);
286 }
287 }
288 catch (ClassNotFoundException cnfe) {
289 }
290 }
291 }
292
293 }