package tc.oc.parse.primitive;
import javax.inject.Inject;
import com.google.common.reflect.TypeToken;
import com.google.inject.TypeLiteral;
import tc.oc.commons.core.reflect.Types;
import tc.oc.parse.ParseException;
import tc.oc.parse.Parser;
import tc.oc.parse.ValueException;
public class EnumParser<T extends Enum<T>> implements Parser<T> {
private final TypeLiteral<T> type;
@Inject private EnumParser(TypeLiteral<T> type) {
this.type = type;
}
@Override
public TypeLiteral<T> paramLiteral() {
return type;
}
@Override
public TypeToken<T> paramToken() {
return Types.toToken(type);
}
@Override
public T parse(String text) throws ParseException {
final Class<T> type = paramClass();
text = text.trim().replace(' ', '_');
try {
// First, try the fast way
return Enum.valueOf(type, text.toUpperCase());
} catch(IllegalArgumentException ex) {
// If that fails, search for a case-insensitive match, without assuming enums are always uppercase
for(T value : type.getEnumConstants()) {
if(value.name().equalsIgnoreCase(text)) return value;
}
throw new ValueException("Unknown " + readableTypeName() + " value '" + text + "'");
}
}
}