Staging
v0.8.1
v0.8.1
swh:1:snp:508923e52305fedd5556b26d8042e0ec70598cef
DefaultFieldSetter.java
package org.pulloid;
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.Collection;
import java.util.Map;
/**
* Allows to set a public field's value or a non-public field's value through a setter method.
*
* @author Romain Laboisse labrom@gmail.com
*/
public class DefaultFieldSetter<T> implements FieldSetter<T> {
@SuppressWarnings("unchecked")
private static final Collection<Class<?>> SUPPORTED_TYPES = new ArrayList<Class<?>>(Arrays.asList(int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class));
private Field field;
private Class<?> fieldType;
private String fieldName;
protected Method setterMethod;
/**
*
* @param targetType
* @param fieldName
*/
DefaultFieldSetter(Class<T> targetType, String fieldName) {
this(targetType, fieldName, null);
}
/**
*
* @param targetType
* @param fieldName
* @param targetFieldType The actual type of the field to set. It can be null.
*/
DefaultFieldSetter(Class<T> targetType, String fieldName, Class<?> targetFieldType) {
// If this is a Map, we'll just call put(String, Object) - we support Map<String, Object> only
if(targetType == null || Map.class.isAssignableFrom(targetType)) {
this.fieldName = fieldName;
this.fieldType = targetFieldType != null ? targetFieldType : String.class; // If not type specified, String is assumed
return;
}
try {
// We don't need to know the field type since we're just looking for the member field with the right name
this.field = targetType.getField(fieldName);
this.fieldType = field.getType();
// If value is not a number and field is a number, the setter will try to convert
return;
} catch(NoSuchFieldException nsfe) {
// No such field, trying setter method
// First search, with the specified field type or String
String setterMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
this.fieldType = targetFieldType != null ? targetFieldType : String.class; // If not type specified, String is assumed
try {
this.setterMethod = targetType.getMethod(setterMethodName, this.fieldType);
return;
} catch (SecurityException se) {
throw new CursorException(se);
} catch (NoSuchMethodException nsme) {
// Second search, on all methods, filter using name and number of params (1)
for(Method m : targetType.getMethods()) {
if(m.getName().equals(setterMethodName)) {
Class<?>[] params = m.getParameterTypes();
if(params.length == 1 && SUPPORTED_TYPES.contains(params[0])) { // Guess we found the right setter method
this.setterMethod = m;
this.fieldType = params[0];
return;
}
}
}
}
throw new CursorException(String.format("Unable to find a field or a setter method for field %1$s in class %2$s", fieldName, targetType.getName()));
}
}
final Object parseValue(Object value) {
if(fieldType == null)
return value;
if(fieldType == Integer.class)
return new Integer(String.valueOf(value));
if(fieldType == Long.class)
return new Long(String.valueOf(value));
if(fieldType == Float.class)
return new Float(String.valueOf(value));
if(fieldType == Double.class)
return new Double(String.valueOf(value));
if(fieldType == int.class)
return Integer.parseInt(String.valueOf(value));
if(fieldType == long.class)
return Long.parseLong(String.valueOf(value));
if(fieldType == float.class)
return Float.parseFloat(String.valueOf(value));
if(fieldType == double.class)
return Double.parseDouble(String.valueOf(value));
return value;
}
@Override
@SuppressWarnings("unchecked")
public boolean set(T target, Object value) {
if(fieldName != null) {
((Map<String, Object>)target).put(fieldName, parseValue(value));
return true;
}
if(field != null) {
// TODO Transform value is needed
try {
field.set(target, parseValue(value));
return true;
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if(setterMethod != null) {
// TODO Transform value is needed
try {
setterMethod.invoke(target, parseValue(value));
return true;
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
String getFieldName() {
if(fieldName != null)
return fieldName;
if(field != null)
return field.getName();
String field = setterMethod.getName().substring(3);
field = field.substring(0, 1).toLowerCase() + field.substring(1);
return field;
}
}