All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simpleflatmapper.csv.CsvMapperFactory Maven / Gradle / Ivy

Go to download

Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.

The newest version!
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() { @Override public Object get() { return new ArrayList(); } }); } CsvMapperBuilder builder = new CsvMapperBuilder(classMeta, mapperConfig, getterFactory, parentBuilder); return builder; } public CsvMapperFactory cellValueReaderFactory(CellValueReaderFactory cellValueReaderFactory) { return addColumnProperty(ConstantPredicate.truePredicate(), new CustomReaderFactoryProperty(cellValueReaderFactory)); } private static class CsvRowSetMapperKeyFactory implements UnaryFactoryWithException, IOException> { @Override public MapperKey newInstance(CsvRowSet csvRowSet) throws IOException { return new MapperKey(csvRowSet.getKeys()); } } private static class CsvRowMapperKeyFactory implements UnaryFactoryWithException, IOException> { @Override public MapperKey newInstance(CsvRow csvRow) throws IOException { return new MapperKey(csvRow.getKeys()); } } private static class SetRowMapperFactory implements UnaryFactory, SetRowMapper> { private final CsvMapperFactory csvMapperFactory; private final ClassMeta classMeta; public SetRowMapperFactory(CsvMapperFactory csvMapperFactory, ClassMeta classMeta) { this.csvMapperFactory = csvMapperFactory; this.classMeta = classMeta; } @Override public SetRowMapper newInstance(MapperKey mapperKey) { final CsvMapperBuilder builder = csvMapperFactory.newBuilder(classMeta); for(CsvColumnKey key : mapperKey.getColumns()) { builder.addMapping(key); } return builder.mapper(); } } public static class DynamicCsvSetRowMapper extends DynamicSetRowMapper implements CsvMapper { public DynamicCsvSetRowMapper( UnaryFactory, SetRowMapper> mapperFactory, UnaryFactoryWithException, IOException> mapperKeyFromRow, UnaryFactoryWithException, IOException> mapperKeyFromSet) { super(mapperFactory, mapperKeyFromRow, mapperKeyFromSet, CsvColumnKeyMapperKeyComparator.INSTANCE); } @Override public String toString() { return "DynamicCsvSetRowMapper{}"; } @Override public > H forEach(Reader reader, H handle) throws IOException, MappingException { forEach(toCsvRowSet(reader, 0, -1), handle); return handle; } @Override public > H forEach(CsvReader reader, H handle) throws IOException, MappingException { forEach(toCsvRowSet(reader, 0 , -1), handle); return handle; } @Override public > H forEach(Reader reader, H handle, int skip) throws IOException, MappingException { forEach(toCsvRowSet(reader, skip, -1), handle); return handle; } @Override public > H forEach(Reader reader, H handle, int skip, int limit) throws IOException, MappingException { forEach(toCsvRowSet(reader, skip, limit), handle); return handle; } @Override public > H forEach(CsvReader reader, H handle, int limit) throws IOException, MappingException { forEach(toCsvRowSet(reader, 0, limit), handle); return handle; } @Override public Iterator iterator(Reader reader) throws IOException { return iterator(toCsvRowSet(reader, 0 , -1)); } @Override public Iterator iterator(CsvReader reader) throws IOException { return iterator(toCsvRowSet(reader, 0 , -1)); } @Override public Iterator iterator(Reader reader, int skip) throws IOException { return iterator(toCsvRowSet(reader, skip , -1)); } //IFJAVA8_START @Override public Stream stream(Reader reader) throws IOException { return stream(toCsvRowSet(reader, 0 , -1)); } @Override public Stream stream(CsvReader reader) throws IOException { return stream(toCsvRowSet(reader, 0 , -1)); } @Override public Stream stream(Reader reader, int skip) throws IOException { return stream(toCsvRowSet(reader, skip , -1)); } //IFJAVA8_END private CsvRowSet toCsvRowSet(Reader reader, int skip, int limit) throws IOException { return toCsvRowSet(CsvParser.reader(reader), skip, limit); } private CsvRowSet toCsvRowSet(CsvReader reader, int skip, int limit) throws IOException { reader.skipRows(skip); return new CsvRowSet(reader, limit); } } }