consulting.omnia.util.cast.CastUtil Maven / Gradle / Ivy
package consulting.omnia.util.cast;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import consulting.omnia.util.cast.collections.ListCastUtil;
import consulting.omnia.util.cast.number.NumberCast;
import consulting.omnia.util.cast.parser.BooleanCastParser;
import consulting.omnia.util.cast.parser.DateCastParser;
import consulting.omnia.util.cast.visitor.AbstractCastMainDataVisitor;
/**
* Cast Util.
* Casts and converts (simple easy conversions) types.
*
* @author Ronaldo Blanc ronaldoblanc at omnia.consulting
* @since Jul 17, 2015
* @version 1.2.0
*/
public class CastUtil {
private static final CastMainDataVisitor CAST_VISITOR = new CastUtil.CastMainDataVisitor();
/**
* Casts or converts the value as type.
* This method is mostly a "number based" converter.
* If you pass a numeric value (number or string) it tries to convert data
* from this numeric value. So, if you try to convert a text format representation
* of a date value like "20150801", you will get undesirable result.
*
* @param value object to cast
* @param type class to cast object as
* @param returning type
* @return if possible returns value
cast as class type
* @throws RuntimeException if anything goes wrong
*/
public static R castAs(final Object value, final Class type) {
if(value == null || type == null) {
throw CastUtilExceptionHandler.castException("Both value and type must be not null");
}
return CAST_VISITOR.asType(value, type);
}
//TODO: improve this method
public static List getAsList(final List> value) {
return ListCastUtil.cast(value);
}
private static class CastMainDataVisitor extends AbstractCastMainDataVisitor {
private Object result;
private Class> type;
public R asType(final Object value, final Class type) {
if (type.isAssignableFrom(value.getClass())) {
return castAs(value, type);
}
this.type = type;
accept(value);
return castAs(result, type);
}
@Override
public void visit(final Character value) {
result = value;
visit(type);
}
@Override
public void visit(final String value) {
result = value;
visit(type);
}
@Override
public void visit(final Date value) {
final BigDecimal number = NumberCast.asNumber(value, BigDecimal.class);;
result = NumberCast.asType(number, type);
}
@Override
public void visit(final Boolean value) {
final Boolean booleanValue = castAs(value, Boolean.class);
result = booleanValue ? NumberCast.asType(BigDecimal.ONE, type) : NumberCast.asType(BigDecimal.ZERO, type);
}
@Override
public void visit(final Number value) {
result = NumberCast.asType(castAs(value, Number.class), this.type);
}
@Override
public void visit(final Class> value) {
// TODO improve this method (remove the 'if's)
if(Boolean.class.isAssignableFrom(type)) {
if(result instanceof String){
result = type.cast(BooleanCastParser.stringToBoolean(castAs(result, String.class)));
return;
}
if(result instanceof Character){
result = type.cast(BooleanCastParser.charToBoolean(castAs(result, Character.class)));
return;
}
}
if (Date.class.isAssignableFrom(type)) {
try {
result = type.cast(DateCastParser.stringToDate(castAs(result, String.class)));
return;
} catch (ParseException e) {
/* Ignored */
}
}
tryAsNumber();
}
private void tryAsNumber() {
try {
final BigDecimal number = NumberCast.asNumber(result, BigDecimal.class);
result = NumberCast.asType(number, type);
} catch(NumberFormatException nfe) {
throw CastUtilExceptionHandler.castException(result, type);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy