package fr.openwide.core.imports.table.opencsv.mapping.column.builder;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Date;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.primitives.Doubles;
import fr.openwide.core.imports.table.common.mapping.AbstractTableImportColumnSet;
import fr.openwide.core.imports.table.common.mapping.column.builder.AbstractTableImportColumnBuilder;
import fr.openwide.core.imports.table.common.mapping.column.builder.ITableImportColumnMapper;
import fr.openwide.core.imports.table.common.mapping.column.builder.MappingConstraint;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.BigDecimalState;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.DateState;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.DoubleState;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.IntegerState;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.LongState;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.StringState;
import fr.openwide.core.imports.table.common.mapping.column.builder.state.TypeState;
import fr.openwide.core.imports.table.opencsv.model.CsvCell;
import fr.openwide.core.imports.table.opencsv.model.CsvCellReference;
import fr.openwide.core.imports.table.opencsv.model.CsvRow;
import fr.openwide.core.imports.table.opencsv.model.CsvTable;
public class OpenCsvImportColumnBuilder extends AbstractTableImportColumnBuilder<CsvTable, CsvRow, CsvCell, CsvCellReference> {
private static final Function<String, Double> DOUBLE_FORMAT_FUNCTION = Doubles.stringConverter();
private static final Function<String, BigDecimal> BIG_DECIMAL_FORMAT_FUNCTION = new Function<String, BigDecimal>() {
@Override
public BigDecimal apply(String input) {
return input == null ? null : new BigDecimal(input);
}
};
private final Function<? super String, ? extends Date> dateFormatFunction;
public OpenCsvImportColumnBuilder(Function<? super String, ? extends Date> dateFormatFunction) {
super();
this.dateFormatFunction = dateFormatFunction;
}
@Override
public OpenCsvTypeState withHeader(AbstractTableImportColumnSet<CsvTable, CsvRow, CsvCell, CsvCellReference> columnSet, String headerLabel,
Predicate<? super String> predicate, int indexAmongMatchedColumns, MappingConstraint mappingConstraint) {
return new OpenCsvTypeState(columnSet, new HeaderLabelOpenCsvImportColumnMapper(headerLabel, predicate, indexAmongMatchedColumns, mappingConstraint));
}
@Override
public OpenCsvTypeState withIndex(AbstractTableImportColumnSet<CsvTable, CsvRow, CsvCell, CsvCellReference> columnSet, int columnIndex) {
return new OpenCsvTypeState(columnSet, new StaticIndexOpenCsvImportColumnMapper(columnIndex));
}
@Override
public OpenCsvTypeState unmapped(AbstractTableImportColumnSet<CsvTable, CsvRow, CsvCell, CsvCellReference> columnSet) {
return new OpenCsvTypeState(columnSet, new UnmappableOpenCsvImportColumnMapper());
}
private class OpenCsvTypeState extends TypeState<CsvTable, CsvRow, CsvCell, CsvCellReference> {
public OpenCsvTypeState(AbstractTableImportColumnSet<CsvTable, CsvRow, CsvCell, CsvCellReference> columnSet,
ITableImportColumnMapper<CsvTable, CsvRow, CsvCell, CsvCellReference> columnMapper) {
super(columnSet, columnMapper);
}
@Override
public IntegerState<CsvTable, CsvRow, CsvCell, CsvCellReference> asInteger() {
return asDouble().toInteger();
}
@Override
public LongState<CsvTable, CsvRow, CsvCell, CsvCellReference> asLong() {
return asDouble().toLong();
}
@Override
public DoubleState<CsvTable, CsvRow, CsvCell, CsvCellReference> asDouble() {
return asString().stripLineBreaks().clean().toDouble(DOUBLE_FORMAT_FUNCTION);
}
@Override
public BigDecimalState<CsvTable, CsvRow, CsvCell, CsvCellReference> asBigDecimal() {
return asString().stripLineBreaks().clean().toBigDecimal(BIG_DECIMAL_FORMAT_FUNCTION);
}
@Override
public StringState<CsvTable, CsvRow, CsvCell, CsvCellReference> asString(final Supplier<? extends NumberFormat> formatIfNumeric) {
return new TypeStateSwitcher<CsvCell>(Functions.<CsvCell>identity()).toString(new Function<CsvCell, String>() {
@Override
public String apply(CsvCell cell) {
if (cell == null) {
return null;
}
return cell.getContent();
}
});
}
@Override
public DateState<CsvTable, CsvRow, CsvCell, CsvCellReference> asDate() {
return asString().toDate(dateFormatFunction);
}
}
}