com.poiji.config.DefaultCasting Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of poiji2 Show documentation
Show all versions of poiji2 Show documentation
Perfect annotation based library to read and write excel files
package com.poiji.config;
import com.poiji.exception.PoijiException;
import com.poiji.option.PoijiOptions;
import com.poiji.parser.BooleanParser;
import com.poiji.parser.Parsers;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
/**
* Created by hakan on 22/01/2017.
*/
public class DefaultCasting implements Casting {
private final boolean errorLoggingEnabled;
private Exception exception;
private final List errors = new ArrayList<>();
public DefaultCasting() {
this(false);
}
public DefaultCasting(boolean errorLoggingEnabled) {
this.errorLoggingEnabled = errorLoggingEnabled;
}
private T onError(String value, String sheetName, int row, int col, Exception exception, T defaultValue) {
logError(value, defaultValue, sheetName, row, col, exception);
return defaultValue;
}
private void logError(String value, Object defaultValue, String sheetName, int row, int col, Exception exception) {
this.exception = exception;
if (errorLoggingEnabled) {
errors.add(new DefaultCastingError(value, defaultValue, sheetName, row, col, exception));
}
}
private boolean primitiveBooleanValue(String value, String sheetName, int row, int col) {
try {
return !value.isEmpty() && Parsers.booleans().parse(value);
} catch (BooleanParser.BooleanParseException bpe) {
return onError(value, sheetName, row, col, bpe, false);
}
}
private Boolean booleanValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : false;
}
return Parsers.booleans().parse(value);
} catch (BooleanParser.BooleanParseException bpe) {
return onError(value, sheetName, row, col, bpe, options.preferNullOverDefault() ? null : false);
}
}
private Byte byteValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : (byte) 0;
}
return Byte.valueOf(trimDecimal(value));
} catch (Exception e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : (byte) 0);
}
}
private byte primitiveByteValue(String value, String sheetName, int row, int col) {
try {
return value.isEmpty() ? (byte) 0 : Byte.parseByte(trimDecimal(value));
} catch (Exception e) {
return onError(value, sheetName, row, col, e, (byte)0);
}
}
private Short shortValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : (short) 0;
}
return Short.valueOf(trimDecimal(value));
} catch (Exception e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : (short) 0);
}
}
private short primitiveShortValue(String value, String sheetName, int row, int col) {
try {
return value.isEmpty() ? (short) 0 : Short.parseShort(trimDecimal(value));
} catch (Exception e) {
return onError(value, sheetName, row, col, e, (short)0);
}
}
private int primitiveIntegerValue(String value, String sheetName, int row, int col) {
try {
return value.isEmpty() ? 0 : Parsers.integers().parse(value).intValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, 0);
}
}
private Integer integerValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : 0;
}
return Parsers.integers().parse(value).intValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, options.preferNullOverDefault() ? null : 0);
}
}
private long primitiveLongValue(String value, String sheetName, int row, int col) {
try {
return value.isEmpty() ? 0 : Parsers.longs().parse(value).longValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, 0L);
}
}
private Long longValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : 0L;
}
return Parsers.longs().parse(value).longValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, options.preferNullOverDefault() ? null : 0L);
}
}
private double primitiveDoubleValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
return value.isEmpty() ? 0d : Parsers.numbers(options.getLocale()).parse(value).doubleValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, 0d);
}
}
private Double doubleValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : 0d;
}
return Parsers.numbers(options.getLocale()).parse(value).doubleValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, options.preferNullOverDefault() ? null : 0d);
}
}
private float primitiveFloatValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
return value.isEmpty() ? 0f : Parsers.numbers(options.getLocale()).parse(value).floatValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, 0f);
}
}
private Float floatValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : 0f;
}
return Parsers.numbers(options.getLocale()).parse(value).floatValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, options.preferNullOverDefault() ? null : 0f);
}
}
private BigDecimal bigDecimalValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : BigDecimal.ZERO;
}
return Parsers.bigDecimals().parse(value);
} catch (NumberFormatException | IllegalStateException e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : BigDecimal.ZERO);
}
}
private Date dateValue(String value, String sheetName, int row, int col, PoijiOptions options) {
//ISSUE #57
//if a date regex has been specified then it wont be null
//so then make sure the string matches the pattern
//if it doesn't, fall back to default
//else continue to turn string into java date
//the reason for this is sometime Java will manage to parse a string to a date object
//without any exceptions but since the string was not an exact match you get a very strange date
if (options.getDateRegex() != null && !value.matches(options.getDateRegex())) {
return options.preferNullOverDefault() ? null : Calendar.getInstance().getTime();
} else {
try {
final SimpleDateFormat sdf = new SimpleDateFormat(options.datePattern());
sdf.setLenient(options.getDateLenient());
return sdf.parse(value);
} catch (ParseException e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : Calendar.getInstance().getTime());
}
}
}
private LocalDate localDateValue(String value, String sheetName, int row, int col, PoijiOptions options) {
//ISSUE #57
//if a date regex has been specified then it wont be null
//so then make sure the string matches the pattern
//if it doesn't, fall back to default
//else continue to turn string into java date
//the reason for this is sometime java will manage to parse a string to a date object
//without any exceptions but since the string was not an exact match you get a very strange date
if (options.getDateRegex() != null && !value.matches(options.getDateRegex())) {
return options.preferNullOverDefault() ? null : LocalDate.now();
} else {
try {
return LocalDate.parse(value, options.dateFormatter());
} catch (DateTimeParseException e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : LocalDate.now());
}
}
}
private LocalDateTime localDateTimeValue(String value, String sheetName, int row, int col, PoijiOptions options) {
if (options.getDateTimeRegex() != null && !value.matches(options.getDateTimeRegex())) {
return options.preferNullOverDefault() ? null : LocalDateTime.now();
} else {
try {
return LocalDateTime.parse(value, options.dateTimeFormatter());
} catch (DateTimeParseException e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : LocalDateTime.now());
}
}
}
private Object enumValue(String value, String sheetName, int row, int col, Class type) {
return Arrays.stream(type.getEnumConstants())
.filter(o -> ((Enum>) o).name().equals(value))
.findFirst()
.orElseGet(() -> {
IllegalArgumentException e = new IllegalArgumentException("No enumeration " + type.getSimpleName() + "." + value);
return onError(value, sheetName, row, col, e, null);
});
}
@Override
public Object castValue(Field field, String rawValue, int row, int col, PoijiOptions options) {
Class> fieldType = field.getType();
return getValueObject(field, row, col, options, rawValue, fieldType);
}
protected Object getValueObject(Field field, int row, int col, PoijiOptions options, String rawValue, Class> fieldType) {
this.exception = null;
String sheetName = options.getSheetName();
String value = options.trimCellValue() ? rawValue.trim() : rawValue;
if (fieldType == int.class) {
return primitiveIntegerValue(value, sheetName, row, col);
} else if (fieldType == Integer.class) {
return integerValue(trimDecimal(value), sheetName, row, col, options);
} else if (fieldType == BigDecimal.class) {
return bigDecimalValue(value, sheetName, row, col, options);
} else if (fieldType == long.class) {
return primitiveLongValue(trimDecimal(value), sheetName, row, col);
} else if (fieldType == Long.class) {
return longValue(trimDecimal(value), sheetName, row, col, options);
} else if (fieldType == double.class) {
return primitiveDoubleValue(value, sheetName, row, col, options);
} else if (fieldType == Double.class) {
return doubleValue(value, sheetName, row, col, options);
} else if (fieldType == float.class) {
return primitiveFloatValue(value, sheetName, row, col, options);
} else if (fieldType == Float.class) {
return floatValue(value, sheetName, row, col, options);
} else if (fieldType == boolean.class) {
return primitiveBooleanValue(value, sheetName, row, col);
} else if (fieldType == Boolean.class) {
return booleanValue(value, sheetName, row, col, options);
} else if (fieldType == byte.class) {
return primitiveByteValue(value, sheetName, row, col);
} else if (fieldType == Byte.class) {
return byteValue(value, sheetName, row, col, options);
} else if (fieldType == short.class) {
return primitiveShortValue(value, sheetName, row, col);
} else if (fieldType == Short.class) {
return shortValue(value, sheetName, row, col, options);
} else if (fieldType == Date.class) {
return dateValue(value, sheetName, row, col, options);
} else if (fieldType == LocalDate.class) {
return localDateValue(value, sheetName, row, col, options);
} else if (fieldType == LocalDateTime.class) {
return localDateTimeValue(value, sheetName, row, col, options);
} else if (fieldType.isEnum()) {
return enumValue(value, sheetName, row, col, fieldType);
} else if (fieldType == List.class || fieldType == Collection.class) {
return castListValue(value, sheetName, row, col, field, options);
} else if (fieldType == Set.class) {
return castSetValue(value, sheetName, row, col, field, options);
} else if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : value;
} else {
return value;
}
}
@Override
public Exception getException() {
return this.exception;
}
private String trimDecimal(final String string){
int i = string.lastIndexOf('.');
if (i == -1){
i = string.lastIndexOf(',');
}
if (i == -1){
return string;
} else {
return string.substring(0, i);
}
}
public boolean isErrorLoggingEnabled() {
return errorLoggingEnabled;
}
public List getErrors() {
if (errorLoggingEnabled) {
return Collections.unmodifiableList(errors);
} else {
throw new PoijiException("logging not enabled");
}
}
private Object castListValue(String value, String sheetName, int row, int col, Field field, PoijiOptions options) {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : emptyList();
}
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
final Type fieldType = genericType.getActualTypeArguments()[0];
final String[] valueList = value.split(options.getListDelimiter());
if (fieldType == Integer.class) {
return Stream.of(valueList).map(rv -> primitiveIntegerValue(rv, sheetName, row, col)).collect(toList());
} else if (fieldType == BigDecimal.class) {
return Stream.of(valueList).map(rv -> bigDecimalValue(rv, sheetName, row, col, options)).collect(toList());
} else if (fieldType == Long.class) {
return Stream.of(valueList).map(rv -> longValue(rv, sheetName, row, col, options)).collect(toList());
} else if (fieldType == Double.class) {
return Stream.of(valueList).map(rv -> doubleValue(rv, sheetName, row, col, options)).collect(toList());
} else if (fieldType == Boolean.class) {
return Stream.of(valueList).map(rv -> booleanValue(rv, sheetName, row, col, options)).collect(toList());
} else if (fieldType == Float.class) {
return Stream.of(valueList).map(rv -> floatValue(rv, sheetName, row, col, options)).collect(toList());
} else {
return Arrays.asList(valueList);
}
}
private Object castSetValue(String value, String sheetName, int row, int col, Field field, PoijiOptions options) {
if (value.isEmpty()) {
return options.preferNullOverDefault() ? null : emptySet();
}
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
final Type fieldType = genericType.getActualTypeArguments()[0];
final String[] valueList = value.split(options.getListDelimiter());
if (fieldType == Integer.class) {
return Stream.of(valueList).map(rv -> primitiveIntegerValue(rv, sheetName, row, col)).collect(toSet());
} else if (fieldType == BigDecimal.class) {
return Stream.of(valueList).map(rv -> bigDecimalValue(rv, sheetName, row, col, options)).collect(toSet());
} else if (fieldType == Long.class) {
return Stream.of(valueList).map(rv -> longValue(rv, sheetName, row, col, options)).collect(toSet());
} else if (fieldType == Double.class) {
return Stream.of(valueList).map(rv -> doubleValue(rv, sheetName, row, col, options)).collect(toSet());
} else if (fieldType == Boolean.class) {
return Stream.of(valueList).map(rv -> booleanValue(rv, sheetName, row, col, options)).collect(toSet());
} else if (fieldType == Float.class) {
return Stream.of(valueList).map(rv -> floatValue(rv, sheetName, row, col, options)).collect(toSet());
} else {
return new HashSet<>(Arrays.asList(valueList));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy