package fr.openwide.core.imports.table.common.mapping.column.builder.state;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Locale;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import fr.openwide.core.commons.util.functional.Predicates2;
import fr.openwide.core.imports.table.common.mapping.AbstractTableImportColumnSet;
import fr.openwide.core.imports.table.common.mapping.column.builder.ITableImportColumnMapper;
public abstract class TypeState<TTable, TRow, TCell, TCellReference> {
public static final class DefaultNumericFormatSupplier implements Supplier<NumberFormat>, Serializable {
private static final long serialVersionUID = 1L;
@Override
public NumberFormat get() {
NumberFormat format = NumberFormat.getNumberInstance(Locale.ROOT);
format.setGroupingUsed(false);
format.setRoundingMode(RoundingMode.HALF_UP);
return format;
}
}
private final AbstractTableImportColumnSet<TTable, TRow, TCell, TCellReference> columnSet;
private final ITableImportColumnMapper<TTable, TRow, TCell, TCellReference> columnMapper;
public TypeState(AbstractTableImportColumnSet<TTable, TRow, TCell, TCellReference> columnSet, ITableImportColumnMapper<TTable, TRow, TCell, TCellReference> columnMapper) {
this.columnSet = columnSet;
this.columnMapper = columnMapper;
}
public abstract IntegerState<TTable, TRow, TCell, TCellReference> asInteger();
public abstract LongState<TTable, TRow, TCell, TCellReference> asLong();
public abstract DoubleState<TTable, TRow, TCell, TCellReference> asDouble();
public abstract BigDecimalState<TTable, TRow, TCell, TCellReference> asBigDecimal();
public StringState<TTable, TRow, TCell, TCellReference> asString() {
return asString(new DefaultNumericFormatSupplier());
}
public abstract StringState<TTable, TRow, TCell, TCellReference> asString(Supplier<? extends NumberFormat> formatIfNumeric);
public abstract DateState<TTable, TRow, TCell, TCellReference> asDate();
protected class TypeStateSwitcher<T> implements ColumnFunctionBuildStateSwitcher<TTable, TRow, TCell, TCellReference, T> {
private final Function<? super TCell, ? extends T> function;
private final Predicate<? super T> mandatoryValuePredicate;
public TypeStateSwitcher(Function<? super TCell, ? extends T> function) {
this(function, Predicates.notNull());
}
public TypeStateSwitcher(Function<? super TCell , ? extends T> function, Predicate<? super T> mandatoryValuePredicate) {
super();
this.function = function;
this.mandatoryValuePredicate = mandatoryValuePredicate;
}
private <T2> TypeStateSwitcher<T2> newSwitcher(Function<? super T, ? extends T2> function2) {
return new TypeStateSwitcher<T2>(Functions.compose(function2, function));
}
private <T2> TypeStateSwitcher<T2> newSwitcher(Function<? super T, ? extends T2> function2, Predicate<? super T2> mandatoryValuePredicate) {
return new TypeStateSwitcher<T2>(Functions.compose(function2, function), mandatoryValuePredicate);
}
@Override
public StringState<TTable, TRow, TCell, TCellReference> toString(final Function<? super T, String> function) {
final TypeStateSwitcher<String> switcher = newSwitcher(function, Predicates2.hasText());
return new StringState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<String> getStateSwitcher() {
return switcher;
}
};
}
@Override
public IntegerState<TTable, TRow, TCell, TCellReference> toInteger(Function<? super T, Integer> function) {
final TypeStateSwitcher<Integer> switcher = newSwitcher(function);
return new IntegerState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<Integer> getStateSwitcher() {
return switcher;
}
};
}
@Override
public LongState<TTable, TRow, TCell, TCellReference> toLong(Function<? super T, Long> function) {
final TypeStateSwitcher<Long> switcher = newSwitcher(function);
return new LongState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<Long> getStateSwitcher() {
return switcher;
}
};
}
@Override
public DoubleState<TTable, TRow, TCell, TCellReference> toDouble(Function<? super T, Double> function) {
final TypeStateSwitcher<Double> switcher = newSwitcher(function);
return new DoubleState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<Double> getStateSwitcher() {
return switcher;
}
};
}
@Override
public BigDecimalState<TTable, TRow, TCell, TCellReference> toBigDecimal(Function<? super T, BigDecimal> function) {
final TypeStateSwitcher<BigDecimal> switcher = newSwitcher(function);
return new BigDecimalState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<BigDecimal> getStateSwitcher() {
return switcher;
}
};
}
@Override
public DateState<TTable, TRow, TCell, TCellReference> toDate(Function<? super T, ? extends Date> function) {
final TypeStateSwitcher<Date> switcher = newSwitcher(function);
return new DateState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<Date> getStateSwitcher() {
return switcher;
}
};
}
@Override
public BooleanState<TTable, TRow, TCell, TCellReference> toBoolean(Function<? super T, Boolean> function) {
final TypeStateSwitcher<Boolean> switcher = newSwitcher(function);
return new BooleanState<TTable, TRow, TCell, TCellReference>() {
@Override
protected TypeStateSwitcher<Boolean> getStateSwitcher() {
return switcher;
}
};
}
@Override
public <TValue> GenericState<TTable, TRow, TCell, TCellReference, TValue> toGeneric(Function<? super T, TValue> function) {
final TypeStateSwitcher<TValue> switcher = newSwitcher(function);
return new GenericState<TTable, TRow, TCell, TCellReference, TValue>() {
@Override
protected TypeStateSwitcher<TValue> getStateSwitcher() {
return switcher;
}
};
}
@Override
public AbstractTableImportColumnSet<TTable, TRow, TCell, TCellReference>.Column<T> build() {
return columnSet.new Column<T>(columnMapper, function, mandatoryValuePredicate);
}
}
}