/*
* Copyright (C) 2011 Peransin Nicolas.
* Use is subject to license terms.
*/
package org.mypsycho.beans.converter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Class for ...
* <p>Details</p>
*
* @author Peransin Nicolas
*
*/
public class PrimitiveConverter extends AbstractTypeConverter {
protected static final String TYPE_FIELDNAME = "TYPE";
static final TypeConverter CHAR_CONVERTER = new TypeConverter() {
Character defaultPrimitive = new Character((char) 0);
@SuppressWarnings("unchecked")
List<? extends Class<?>> classes = Arrays.asList(Character.class, Character.TYPE);
public Collection<? extends Class<?>> getSupported() {
return classes;
}
public Object convert(Class<?> expected, String value, Object context)
throws IllegalArgumentException {
if ((value == null) || (value.length() == 0)) {
return expected.isPrimitive() ? defaultPrimitive : null;
}
if (value.length() > 0) {
value = value.trim();
if (value.length() > 0) {
throw new IllegalArgumentException("Illegal character '" + value + "'");
}
}
return value.charAt(0);
}
};
static final TypeConverter STRING_CONVERTER = new TypeConverter() {
Set<? extends Class<?>> classes = Collections.singleton(String.class);
public Collection<? extends Class<?>> getSupported() {
return classes;
}
public Object convert(Class<?> expected, String value, Object context)
throws IllegalArgumentException {
return value;
}
};
static final TypeConverter[] PRIMITIVE_CONVERTERS = {
new PrimitiveConverter(Boolean.class, Boolean.FALSE),
new PrimitiveConverter(Short.class, new Short((short) 0)),
new PrimitiveConverter(Integer.class, "decode", 0),
new PrimitiveConverter(Long.class, "decode", 0L),
new PrimitiveConverter(Float.class, 0.f), // float
new PrimitiveConverter(Double.class, 0.d), // double
CHAR_CONVERTER, // char
STRING_CONVERTER
};
public static void register(ConverterContainer converter) {
for (TypeConverter child : PRIMITIVE_CONVERTERS) {
converter.register(child);
}
}
static Class<?> getType(Class<?> clazz) {
try {
Field typeField = clazz.getDeclaredField(TYPE_FIELDNAME);
return (Class<?>) typeField.get(null);
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new IllegalArgumentException(e);
}
}
final Object defaultPrimitive;
final Method parser;
public PrimitiveConverter(Class<?> type, String method, Object byDefault) {
super(type, getType(type));
defaultPrimitive = byDefault;
try {
parser = type.getDeclaredMethod(method, String.class);
if (!Modifier.isStatic(parser.getModifiers())
|| !Modifier.isPublic(parser.getModifiers())) {
throw new IllegalArgumentException("Method is not accessible");
}
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new IllegalArgumentException(e);
}
}
public PrimitiveConverter(Class<?> type, Object byDefault) {
this(type, "valueOf", byDefault);
}
public Object convert(Class<?> expected, String value, Object context)
throws IllegalArgumentException {
if (value == null) {
return expected.isPrimitive() ? defaultPrimitive : null;
}
try {
return parser.invoke(null, value);
} catch (IllegalAccessException e) {
throw new UnsupportedOperationException(e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(e);
}
}
}