package com.googlecode.mycontainer.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ReflectionUtil {
public static void setBeanField(Object entidade, String key, Object value) {
try {
String methodName = toMethodName("set", key);
Method method = null;
if (value != null) {
method = ReflectionUtil.getMethod(entidade, methodName, value.getClass());
}
if (method == null) {
Class<?> type = ReflectionUtil.getBeanFieldType(entidade, key);
method = ReflectionUtil.getMethod(entidade, methodName, type);
}
if (method == null && value == null) {
throw new RuntimeException("impossible to guess type for field: " + key);
}
Class<?> paramType = method.getParameterTypes()[0];
if (value != null && !paramType.isAssignableFrom(value.getClass())) {
throw new RuntimeException("this method " + method + " can not be invoked with: " + value.getClass().getName());
}
method.invoke(entidade, new Object[] { value });
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static String toMethodName(String pre, String key) {
char c = Character.toUpperCase(key.charAt(0));
return "" + pre + c + key.substring(1);
}
public static List<String> getBeanFields(Object obj) {
Class<?> clazz = obj.getClass();
return getBeanFieldsOfClass(clazz);
}
public static List<String> getBeanFieldsOfClass(Class<?> clazz) {
List<String> ret = new ArrayList<String>();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getParameterTypes().length != 0) {
continue;
}
String name = method.getName();
if (!name.startsWith("get") || name.equals("getClass")) {
continue;
}
Class<?> type = method.getReturnType();
String fieldName = toBeanFieldName(name);
if (getMethodOfClass(clazz, toMethodName("set", fieldName), new Class[] { type }) != null) {
ret.add(fieldName);
}
}
return ret;
}
private static String toBeanFieldName(String name) {
char c = Character.toLowerCase(name.charAt(3));
return "" + c + name.substring(4);
}
public static Object getBeanField(Object obj, String fieldName) {
try {
String methodName = toMethodName("get", fieldName);
Method method = getMethod(obj, methodName);
return method.invoke(obj);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static Method getMethod(Object obj, String methodName, Class<?>... types) {
Class<?> clazz = obj.getClass();
return getMethodOfClass(clazz, methodName, types);
}
public static Method getMethodOfClass(Class<?> clazz, String methodName, Class<?>... types) {
try {
return clazz.getMethod(methodName, types);
} catch (NoSuchMethodException e) {
return null;
} catch (SecurityException e) {
throw new RuntimeException(e);
}
}
public static boolean isBeanFieldAnnotated(Object obj, String fieldName, Class<? extends Annotation> annotation) {
Class<?> clazz = obj.getClass();
return isBeanFieldAnnotated(clazz, fieldName, annotation);
}
public static boolean isBeanFieldAnnotated(Class<?> clazz, String fieldName, Class<? extends Annotation> annotation) {
Method method = getMethodOfClass(clazz, toMethodName("get", fieldName));
if (method == null) {
return false;
}
return method.isAnnotationPresent(annotation);
}
public static Class<?> getBeanFieldType(Object obj, String fieldName) {
return getBeanFieldTypeOfClass(obj.getClass(), fieldName);
}
public static Class<?> getBeanFieldTypeOfClass(Class<?> clazz, String fieldName) {
Method method = getMethodOfClass(clazz, toMethodName("get", fieldName));
if (method == null) {
throw new RuntimeException("Bean field '" + fieldName + "' not found in " + clazz);
}
return method.getReturnType();
}
public static void checkBeanFieldAnnotated(Class<?> clazz, String fieldName, Class<? extends Annotation> annotation) {
if (!ReflectionUtil.isBeanFieldAnnotated(clazz, fieldName, annotation)) {
throw new IllegalStateException("Requires " + annotation + " on " + clazz.getName() + "." + fieldName);
}
}
public static List<Method> getMethods(Class<?> clazz, int modifier) {
Method[] methods = clazz.getMethods();
List<Method> ret = new ArrayList<Method>();
for (Method method : methods) {
int result = method.getModifiers() & modifier;
if (result > 0) {
ret.add(method);
}
}
return ret;
}
public static List<Method> getMethods(Class<?> clazz) {
return getMethods(clazz, 0xFFFFFFFF);
}
public static List<Annotation> getAnnotation(Method method) {
Annotation[] annotations = method.getAnnotations();
if (annotations == null || annotations.length == 0) {
return Collections.emptyList();
}
return Arrays.asList(annotations);
}
public static List<Annotation> getAnnotationField(Field field) {
Annotation[] annotations = field.getAnnotations();
if (annotations == null || annotations.length == 0) {
return Collections.emptyList();
}
return Arrays.asList(annotations);
}
public static List<Annotation> getAnnotationClass(Class<?> clazz) {
Annotation[] annotations = clazz.getAnnotations();
if (annotations == null || annotations.length == 0) {
return Collections.emptyList();
}
return Arrays.asList(annotations);
}
public static List<Field> getFields(Class<?> clazz) {
Field[] fields = clazz.getDeclaredFields();
List<Field> ret = new ArrayList<Field>(Arrays.asList(fields));
Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {
ret.addAll(getFields(superclass));
}
return ret;
}
public static List<Method> getDeclaringMethods(Class<?> clazz) {
return getDeclaringMethods(clazz, 0xFFFFFFFF);
}
public static List<Method> getDeclaringMethods(Class<?> clazz, int modifier) {
Method[] methods = clazz.getDeclaredMethods();
List<Method> ret = new ArrayList<Method>();
for (Method method : methods) {
int result = method.getModifiers() & modifier;
if (result > 0) {
ret.add(method);
}
}
return ret;
}
public static Object invoke(Object o, Method m, Object... args) {
try {
return m.invoke(o, args);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public static Method getMethodByName(Class<?> clazz, String methodName) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
boolean equals = method.getName().equals(methodName);
if (equals) {
return method;
}
}
Class<Object> superclass = (Class<Object>) clazz.getSuperclass();
if (superclass == null) {
return null;
}
return getMethodByName(superclass, methodName);
}
public static boolean hasBeanField(Object obj, String fieldName) {
try {
String methodName = toMethodName("get", fieldName);
Method method = getMethod(obj, methodName);
return method != null;
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
}
public static Object newInstance(String className) {
Class<?> clazz = requireClazz(className);
return newInstance(clazz);
}
@SuppressWarnings("unchecked")
public static <T> Class<T> clazz(String className) {
try {
return (Class<T>) Class.forName(className);
} catch (ClassNotFoundException e) {
return null;
}
}
public static String debug(Class<?> clazz) {
if (clazz == null) {
return "null";
}
StringBuilder ret = new StringBuilder();
ret.append("[").append(clazz.getName());
String url = debugLocation(clazz);
if (url != null) {
ret.append(" ").append(url);
}
ret.append(']');
return ret.toString();
}
private static String debugLocation(Class<?> clazz) {
try {
return clazz.getProtectionDomain().getCodeSource().getLocation().toString();
} catch (Exception e) {
return "null";
}
}
public static Object invokeStatic(Class<?> clazz, String methodName, Class<?>[] types, Object[] args) {
try {
Method method = ReflectionUtil.getMethodOfClass(clazz, methodName, types);
return method.invoke(null, args[0]);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static <T> T newInstance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static List<Annotation> getBeanFieldsAnnotations(Class<?> clazz, String fieldName) {
Method method = getMethodOfClass(clazz, toMethodName("get", fieldName));
return getAnnotation(method);
}
public static List<Annotation> getBeanFieldsAnnotationsField(Class<?> clazz, String fieldName) {
try {
if ("lastModified".equals(fieldName)) {
return new ArrayList<Annotation>();
} else {
Field field = clazz.getDeclaredField(fieldName);
return getAnnotationField(field);
}
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public static <T> T newInstance(Class<T> clazz, Class<?>[] types, Object... values) {
try {
Constructor<?> cons = clazz.getConstructor(types);
T ret = (T) cons.newInstance(values);
return ret;
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public static <T> Class<T> requireClazz(String name) {
try {
return (Class<T>) Class.forName(name);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}