org.simpleflatmapper.csv.CsvMapperFactory Maven / Gradle / Ivy
Show all versions of sfm-csv Show documentation
package org.simpleflatmapper.csv;
import org.simpleflatmapper.csv.impl.CsvColumnDefinitionProviderImpl;
import org.simpleflatmapper.csv.mapper.CsvMappingContextFactoryBuilder;
import org.simpleflatmapper.csv.mapper.CsvRowGetterFactory;
import org.simpleflatmapper.csv.property.CustomReaderFactoryProperty;
import org.simpleflatmapper.csv.property.CustomReaderProperty;
import org.simpleflatmapper.lightningcsv.CsvReader;
import org.simpleflatmapper.lightningcsv.StringReader;
import org.simpleflatmapper.map.MapperBuildingException;
import org.simpleflatmapper.map.MapperConfig;
import org.simpleflatmapper.map.MappingException;
import org.simpleflatmapper.map.Result;
import org.simpleflatmapper.map.ResultFieldMapperErrorHandler;
import org.simpleflatmapper.map.SetRowMapper;
import org.simpleflatmapper.map.mapper.AbstractColumnDefinitionProvider;
import org.simpleflatmapper.map.mapper.AbstractColumnNameDiscriminatorMapperFactory;
import org.simpleflatmapper.map.mapper.DynamicSetRowMapper;
import org.simpleflatmapper.map.mapper.MapperKey;
import org.simpleflatmapper.map.mapper.TransformSetRowMapper;
import org.simpleflatmapper.map.property.DefaultDateFormatProperty;
import org.simpleflatmapper.reflect.ParameterizedTypeImpl;
import org.simpleflatmapper.util.CheckedConsumer;
import org.simpleflatmapper.util.ConstantPredicate;
import org.simpleflatmapper.util.Function;
import org.simpleflatmapper.util.Supplier;
import org.simpleflatmapper.util.TypeReference;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import org.simpleflatmapper.util.UnaryFactory;
import org.simpleflatmapper.util.UnaryFactoryWithException;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
//IFJAVA8_START
import java.util.stream.Stream;
//IFJAVA8_END
/**
* CsvMapperFactory is not Thread-Safe but the mappers are.
* It is strongly advised to instantiate one jdbcMapper per class for the life of your application.
*
* You can instantiate dynamic jdbcMapper which will use the name line of the csv file
* to figure out the list of the columns or a static one using a builder.
*
*
* // create a dynamic jdbcMapper targeting MyClass
* CsvMapperFactory
* .newInstance()
* .newMapper(MyClass.class);
*
* // create a static jdbcMapper targeting MyClass
* CsvMapperFactory
* .newInstance()
* .newBuilder(MyClass.class)
* .addMapping("id")
* .addMapping("field1")
* .addMapping("field2")
* .mapper();
*
*
*/
public final class CsvMapperFactory extends AbstractColumnNameDiscriminatorMapperFactory {
/**
* instantiate a new JdbcMapperFactory
* @return a new JdbcMapperFactory
*/
public static CsvMapperFactory newInstance() {
return new CsvMapperFactory();
}
public static CsvMapperFactory newInstance(AbstractColumnDefinitionProvider columnDefinitionProvider) {
return new CsvMapperFactory(columnDefinitionProvider);
}
public static CsvMapperFactory newInstance(CsvMapperFactory cfg) {
return new CsvMapperFactory(cfg);
}
private String defaultDateFormat = CsvMapperBuilder.DEFAULT_DATE_FORMAT;
private CsvMapperFactory(AbstractColumnDefinitionProvider columnDefinitionProvider) {
super(columnDefinitionProvider, CsvColumnDefinition.identity(), CsvRowGetterFactory.INSTANCE);
}
private CsvMapperFactory() {
super(new CsvColumnDefinitionProviderImpl(), CsvColumnDefinition.identity(), CsvRowGetterFactory.INSTANCE);
}
private CsvMapperFactory(CsvMapperFactory parent) {
super(parent);
this.defaultDateFormat = parent.defaultDateFormat;
}
@Override
public AbstractColumnDefinitionProvider enrichColumnDefinitions(AbstractColumnDefinitionProvider columnDefinitions) {
AbstractColumnDefinitionProvider copy = columnDefinitions.copy();
copy.addColumnProperty(ConstantPredicate.truePredicate(), new DefaultDateFormatProperty(defaultDateFormat));
return copy;
}
public CsvMapperFactory defaultDateFormat(final String defaultDateFormat) {
this.defaultDateFormat = defaultDateFormat;
return this;
}
public CsvMapperFactory addCustomValueReader(String key, CellValueReader> cellValueReader) {
return addColumnProperty(key, new CustomReaderProperty(cellValueReader));
}
public CsvMapperFactory addCustomValueReader(String key, StringReader> stringReader) {
return addColumnProperty(key, new CustomReaderProperty(stringReader));
}
/**
*
* @param target the targeted class for the jdbcMapper
* @param the targeted type
* @return a jdbc jdbcMapper that will map to the targeted class.
* @throws MapperBuildingException if an error occurs building the jdbcMapper
*/
public CsvMapper newMapper(final Class target) throws MapperBuildingException {
return newMapper((Type)target);
}
public CsvMapper newMapper(final TypeReference target) throws MapperBuildingException {
return newMapper(target.getType());
}
public CsvMapper newMapper(final Type target) throws MapperBuildingException {
final ClassMeta classMeta = getClassMeta(target);
return newMapper(classMeta);
}
public CsvMapper newMapper(final ClassMeta classMeta) throws MapperBuildingException {
return new DynamicCsvSetRowMapper(new SetRowMapperFactory(this, classMeta), new CsvRowMapperKeyFactory(), new CsvRowSetMapperKeyFactory());
}
public CsvMapper> newErrorCollectingMapper(final Class target) throws MapperBuildingException {
return newErrorCollectingMapper((Type)target);
}
public CsvMapper> newErrorCollectingMapper(final TypeReference target) throws MapperBuildingException {
return newErrorCollectingMapper(target.getType());
}
public CsvMapper> newErrorCollectingMapper(final Type target) throws MapperBuildingException {
final ClassMeta> classMeta = getClassMeta(new ParameterizedTypeImpl(Result.ResultBuilder.class, target, CsvColumnKey.class));
CsvMapperFactory csvMapperFactory = new CsvMapperFactory(this)
.fieldMapperErrorHandler(new ResultFieldMapperErrorHandler());
final SetRowMapperFactory> setRowMapperFactory = new SetRowMapperFactory>(csvMapperFactory, classMeta);
return new DynamicCsvSetRowMapper>(
new UnaryFactory, SetRowMapper, IOException>>() {
@Override
public SetRowMapper, IOException> newInstance(MapperKey csvColumnKeyMapperKey) {
SetRowMapper, IOException> rowMapper = setRowMapperFactory.newInstance(csvColumnKeyMapperKey);
return new TransformSetRowMapper, Result, IOException>(
rowMapper,
new Function, Result>() {
@Override
public Result apply(Result.ResultBuilder tCsvColumnKeyResultBuilder) {
return tCsvColumnKeyResultBuilder.build();
}
}
);
}
}, new CsvRowMapperKeyFactory(), new CsvRowSetMapperKeyFactory());
}
/**
* Will create a newInstance of ResultSetMapperBuilder
* @param target the target class of the jdbcMapper
* @param the targeted type
* @return a builder ready to instantiate a jdbcMapper or to be customized
* @throws MapperBuildingException if an error occurs building the jdbcMapper
*/
public CsvMapperBuilder newBuilder(final Class target) {
return newBuilder((Type)target);
}
public CsvMapperBuilder newBuilder(final TypeReference target) {
return newBuilder(target.getType());
}
public CsvMapperBuilder newBuilder(final Type target) {
final ClassMeta classMeta = getClassMeta(target);
return newBuilder(classMeta);
}
public CsvMapperBuilder newBuilder(final ClassMeta classMeta) {
MapperConfig mapperConfig = mapperConfig(classMeta.getType());
CsvMappingContextFactoryBuilder parentBuilder = new CsvMappingContextFactoryBuilder(!mapperConfig.unorderedJoin());
if (mapperConfig.fieldMapperErrorHandler() instanceof ResultFieldMapperErrorHandler) {
parentBuilder.addSupplier(new Supplier