001
014
015 package com.liferay.portal.kernel.util;
016
017 import java.lang.annotation.Annotation;
018 import java.lang.reflect.Field;
019 import java.lang.reflect.Method;
020 import java.lang.reflect.Modifier;
021 import java.lang.reflect.ParameterizedType;
022 import java.lang.reflect.Type;
023
024 import java.util.Arrays;
025 import java.util.HashSet;
026 import java.util.LinkedHashSet;
027 import java.util.Set;
028
029
034 public class ReflectionUtil {
035
036 public static Object arrayClone(Object array) {
037 Class<?> clazz = array.getClass();
038
039 if (!clazz.isArray()) {
040 throw new IllegalArgumentException(
041 "Input object is not an array: " + array);
042 }
043
044 try {
045 return _CLONE_METHOD.invoke(array);
046 }
047 catch (Exception e) {
048 return throwException(e);
049 }
050 }
051
052 public static Class<?> getAnnotationDeclaringClass(
053 Class<? extends Annotation> annotationClass, Class<?> clazz) {
054
055 if ((clazz == null) || clazz.equals(Object.class)) {
056 return null;
057 }
058
059 if (isAnnotationDeclaredInClass(annotationClass, clazz)) {
060 return clazz;
061 }
062 else {
063 return getAnnotationDeclaringClass(
064 annotationClass, clazz.getSuperclass());
065 }
066 }
067
068 public static Field getDeclaredField(Class<?> clazz, String name)
069 throws Exception {
070
071 Field field = clazz.getDeclaredField(name);
072
073 if (!field.isAccessible()) {
074 field.setAccessible(true);
075 }
076
077 return unfinalField(field);
078 }
079
080 public static Method getDeclaredMethod(
081 Class<?> clazz, String name, Class<?> ... parameterTypes)
082 throws Exception {
083
084 Method method = clazz.getDeclaredMethod(name, parameterTypes);
085
086 if (!method.isAccessible()) {
087 method.setAccessible(true);
088 }
089
090 return method;
091 }
092
093 public static Class<?> getGenericSuperType(Class<?> clazz) {
094 try {
095 ParameterizedType parameterizedType =
096 (ParameterizedType)clazz.getGenericSuperclass();
097
098 Type[] types = parameterizedType.getActualTypeArguments();
099
100 if (types.length > 0) {
101 return (Class<?>)types[0];
102 }
103 }
104 catch (Throwable t) {
105 }
106
107 return null;
108 }
109
110 public static Class<?>[] getInterfaces(Object object) {
111 return getInterfaces(object, null);
112 }
113
114 public static Class<?>[] getInterfaces(
115 Object object, ClassLoader classLoader) {
116
117 Set<Class<?>> interfaceClasses = new LinkedHashSet<Class<?>>();
118
119 Class<?> clazz = object.getClass();
120
121 _getInterfaces(interfaceClasses, clazz, classLoader);
122
123 Class<?> superClass = clazz.getSuperclass();
124
125 while (superClass != null) {
126 _getInterfaces(interfaceClasses, superClass, classLoader);
127
128 superClass = superClass.getSuperclass();
129 }
130
131 return interfaceClasses.toArray(new Class<?>[interfaceClasses.size()]);
132 }
133
134 public static Class<?>[] getParameterTypes(Object[] arguments) {
135 if (arguments == null) {
136 return null;
137 }
138
139 Class<?>[] parameterTypes = new Class<?>[arguments.length];
140
141 for (int i = 0; i < arguments.length; i++) {
142 if (arguments[i] == null) {
143 parameterTypes[i] = null;
144 }
145 else if (arguments[i] instanceof Boolean) {
146 parameterTypes[i] = Boolean.TYPE;
147 }
148 else if (arguments[i] instanceof Byte) {
149 parameterTypes[i] = Byte.TYPE;
150 }
151 else if (arguments[i] instanceof Character) {
152 parameterTypes[i] = Character.TYPE;
153 }
154 else if (arguments[i] instanceof Double) {
155 parameterTypes[i] = Double.TYPE;
156 }
157 else if (arguments[i] instanceof Float) {
158 parameterTypes[i] = Float.TYPE;
159 }
160 else if (arguments[i] instanceof Integer) {
161 parameterTypes[i] = Integer.TYPE;
162 }
163 else if (arguments[i] instanceof Long) {
164 parameterTypes[i] = Long.TYPE;
165 }
166 else if (arguments[i] instanceof Short) {
167 parameterTypes[i] = Short.TYPE;
168 }
169 else {
170 parameterTypes[i] = arguments[i].getClass();
171 }
172 }
173
174 return parameterTypes;
175 }
176
177 public static Set<Method> getVisibleMethods(Class<?> clazz) {
178 Set<Method> visibleMethods = new HashSet<Method>(
179 Arrays.asList(clazz.getMethods()));
180
181 visibleMethods.addAll(Arrays.asList(clazz.getDeclaredMethods()));
182
183 while ((clazz = clazz.getSuperclass()) != null) {
184 for (Method method : clazz.getDeclaredMethods()) {
185 int modifiers = method.getModifiers();
186
187 if (!Modifier.isPrivate(modifiers) &
188 !Modifier.isPublic(modifiers)) {
189
190 visibleMethods.add(method);
191 }
192 }
193 }
194
195 return visibleMethods;
196 }
197
198 public static boolean isAnnotationDeclaredInClass(
199 Class<? extends Annotation> annotationClass, Class<?> clazz) {
200
201 if ((annotationClass == null) || (clazz == null)) {
202 throw new IllegalArgumentException();
203 }
204
205 Annotation[] annotations = clazz.getAnnotations();
206
207 for (Annotation annotation : annotations) {
208 if (annotationClass.equals(annotation.annotationType())) {
209 return true;
210 }
211 }
212
213 return false;
214 }
215
216 public static <T> T throwException(Throwable throwable) {
217 return ReflectionUtil.<T, RuntimeException>_doThrowException(throwable);
218 }
219
220 public static Field unfinalField(Field field) throws Exception {
221 int modifiers = field.getModifiers();
222
223 if ((modifiers & Modifier.FINAL) == Modifier.FINAL) {
224 Field modifiersField = getDeclaredField(Field.class, "modifiers");
225
226 modifiersField.setInt(field, modifiers & ~Modifier.FINAL);
227 }
228
229 return field;
230 }
231
232 @SuppressWarnings("unchecked")
233 private static <T, E extends Throwable> T _doThrowException(
234 Throwable throwable)
235 throws E {
236
237 throw (E)throwable;
238 }
239
240 private static void _getInterfaces(
241 Set<Class<?>> interfaceClasses, Class<?> clazz,
242 ClassLoader classLoader) {
243
244 for (Class<?> interfaceClass : clazz.getInterfaces()) {
245 try {
246 if (classLoader != null) {
247 interfaceClasses.add(
248 classLoader.loadClass(interfaceClass.getName()));
249 }
250 else {
251 interfaceClasses.add(interfaceClass);
252 }
253 }
254 catch (ClassNotFoundException cnfe) {
255 }
256 }
257 }
258
259 private static final Method _CLONE_METHOD;
260
261 static {
262 try {
263 _CLONE_METHOD = getDeclaredMethod(Object.class, "clone");
264 }
265 catch (Exception e) {
266 throw new ExceptionInInitializerError(e);
267 }
268 }
269
270 }