package com.google.code.joto.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
import com.thoughtworks.xstream.converters.reflection.ImmutableFieldKeySorter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.core.JVM;
public class ReflectUtils {
private static JVM jvm = new JVM();
private static ReflectionProvider reflectionProvider = jvm.bestReflectionProvider();
private static FieldDictionary fieldDictionary = new FieldDictionary(new ImmutableFieldKeySorter());
// -------------------------------------------------------------------------
/** private to force all static */
private ReflectUtils() {
}
// -------------------------------------------------------------------------
public static ReflectionProvider getReflectionProvider() {
return reflectionProvider;
}
public static FieldDictionary getFieldDictionary() {
return fieldDictionary;
}
public static String fieldToCapitalizedName(Field field) {
return fieldToCapitalizedName(field.getName());
}
public static String fieldToCapitalizedName(String fieldName) {
String res = fieldName;
if (res.startsWith("_")) {
// detect "_field" naming convention
res = res.substring(1);
}
int len = res.length();
if (len == 1) {
res = "" + Character.toUpperCase(res.charAt(0));
} else {
char ch0 = res.charAt(0);
if (len > 2 && (ch0 == 'm' || ch0 == 'f')
&& Character.isUpperCase(res.charAt(1))) {
// detect "mField" and "fField" naming conventions...
res = res.substring(1);
}
// ok.. now transform "field" into "Field"
res = Character.toUpperCase(res.charAt(0)) + ((res.length() > 1)? res.substring(1, res.length()) : "");
}
if (res.endsWith("_")) {
res = res.substring(0, res.length() - 1);
}
return res;
}
/**
*
* @param methodPrefix
* @param field
* @param methodSuffix
* @param parameterTypes
* @return
*/
public static Method findFieldMethod(
String methodPrefix, Field field, String methodSuffix,
Class <?>... parameterTypes) {
String methodName = ((methodPrefix != null)? methodPrefix : "")
+ fieldToCapitalizedName(field)
+ ((methodSuffix != null)? methodSuffix : "");
Method res = findMethod(field.getDeclaringClass(), methodName, parameterTypes);
return res;
}
public static Method findMethod(Class<?> clss,
String methodName, Class<?>... parameterTypes) {
try {
return clss.getMethod(methodName, parameterTypes);
} catch(NoSuchMethodException ex) {
return null;
} catch(Exception ex) {
throw new RuntimeException("Failed to find method", ex);
}
}
public static List<Method> findMethodsByName(Class<?> clss, String methodName, boolean onlyPublic) {
List<Method> res = new ArrayList<Method>();
for (Method meth : clss.getMethods()) {
if (meth.getName().equals(methodName)
&& (!onlyPublic || Modifier.isPublic(meth.getModifiers()))
) {
res.add(meth);
}
}
return res;
}
// /**
// * TOCHECK ... see Class.getMethod(name, parameterTypes) ???
// *
// */
// public static Method findMethod(Class clssOrSuperClasses, String methodName, Class<?>... argTypes) {
// Method res = null;
// for(Class<?> clss = clssOrSuperClasses; !Object.class.equals(clss); clss = clss.getSuperclass()) {
// Method tmp = findDeclaredMethod(clss, methodName, argTypes);
// if (tmp != null) {
// res = tmp;
// break;
// }
// }
// return res;
// }
//
// public static Method findDeclaredMethod(Class declaredClss, String methodName, Class<?>... argTypes) {
// ...
// }
public static Method methodIfPublic(Method meth) {
if (meth == null) return null;
Method res = null;
int modifiers = meth.getModifiers();
if (meth.isAccessible()
&& Modifier.isPublic(modifiers)) {
res = meth;
}
return res;
}
public static List<Field> findAssignableFieldsForValueType(Class<?> targetClass, Class<?> valueType) {
List<Field> res = new ArrayList<Field>();
for (Iterator<Field> iterator = fieldsFor(targetClass); iterator.hasNext();) {
Field field = iterator.next();
Class<?> fieldClass = field.getDeclaringClass();
if (fieldClass.isAssignableFrom(valueType)) {
res.add(field);
}
}
return res;
}
@SuppressWarnings("unchecked")
public static Iterator<Field> fieldsFor(Class<?> targetClass) {
return fieldDictionary.fieldsFor(targetClass);
}
public static Class<?> primitiveTypeToWrapperType(Class<?> t) {
if (t == java.lang.Boolean.TYPE) return java.lang.Boolean.class;
else if (t == java.lang.Character.TYPE) return java.lang.Character.class;
else if (t == java.lang.Byte.TYPE) return java.lang.Byte.class;
else if (t == java.lang.Short.TYPE) return java.lang.Short.class;
else if (t == java.lang.Integer.TYPE) return java.lang.Integer.class;
else if (t == java.lang.Long.TYPE) return java.lang.Long.class;
else if (t == java.lang.Float.TYPE) return java.lang.Float.class;
else if (t == java.lang.Double.TYPE) return java.lang.Double.class;
else if (t == java.lang.Void.TYPE) return java.lang.Void.class;
else return null;
}
public static boolean isPrimitiveWrapperType(Class<?> t) {
return t.getName().startsWith("java.lang.")
&& wrapperTypeToPrimitive(t) != null;
}
public static Class<?> wrapperTypeToPrimitive(Class<?> t) {
if (t == java.lang.Boolean.class) return java.lang.Boolean.TYPE;
else if (t == java.lang.Character.class) return java.lang.Character.TYPE;
else if (t == java.lang.Byte.class) return java.lang.Byte.TYPE;
else if (t == java.lang.Short.class) return java.lang.Short.TYPE;
else if (t == java.lang.Integer.class) return java.lang.Integer.TYPE;
else if (t == java.lang.Long.class) return java.lang.Long.TYPE;
else if (t == java.lang.Float.class) return java.lang.Float.TYPE;
else if (t == java.lang.Double.class) return java.lang.Double.TYPE;
else if (t == java.lang.Void.class) return java.lang.Void.TYPE;
else return null;
}
}