org.sfm.csv.DynamicCsvMapper Maven / Gradle / Ivy
package org.sfm.csv;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.sfm.csv.cell.StringCellValueReader;
import org.sfm.csv.parser.CharsCellHandler;
import org.sfm.csv.parser.CsvParser;
import org.sfm.map.FieldMapperErrorHandler;
import org.sfm.map.MapperBuilderErrorHandler;
import org.sfm.map.MapperCache;
import org.sfm.map.MapperKey;
import org.sfm.map.MappingException;
import org.sfm.reflect.ReflectionService;
import org.sfm.reflect.meta.ClassMeta;
import org.sfm.utils.RowHandler;
public class DynamicCsvMapper implements CsvMapper {
public final class DynamicCellHandler implements CharsCellHandler {
private final RowHandler handle;
private final int rowStart;
private final int limit;
private CsvMapperCellHandler cellHandler;
private List columns = new ArrayList();
private int currentRow;
public DynamicCellHandler(RowHandler handle, int rowStart, int limit) {
this.handle = handle;
this.rowStart = rowStart;
this.limit = limit;
}
@Override
public boolean endOfRow() {
if (rowStart == -1 || currentRow >= rowStart) {
if (cellHandler == null) {
MapperKey key = new MapperKey(columns.toArray(new String[columns.size()]));
CsvMapperImpl csvMapperImpl = mapperCache.get(key);
if (csvMapperImpl == null) {
csvMapperImpl = buildeMapper(key);
mapperCache.add(key, csvMapperImpl);
}
cellHandler = csvMapperImpl.newCellHandler(handle);
} else {
cellHandler.endOfRow();
}
}
return continueProcessing();
}
private boolean continueProcessing() {
boolean continueProcessing = limit == -1 || (currentRow - rowStart) < limit;
currentRow++;
return continueProcessing;
}
@Override
public void newCell(char[] chars, int offset, int length) {
if (rowStart == -1 || currentRow >= rowStart) {
if (cellHandler == null) {
columns.add(StringCellValueReader.readString(chars, offset, length));
} else {
cellHandler.newCell(chars, offset, length);
}
}
}
@Override
public void end() {
if (cellHandler != null) {
cellHandler.end();
}
}
}
private final ClassMeta classMeta;
private final Class target;
private final CsvParser csvParser;
private final FieldMapperErrorHandler fieldMapperErrorHandler;
private final MapperBuilderErrorHandler mapperBuilderErrorHandler;
private final String defaultDateFormat;
private MapperCache> mapperCache = new MapperCache>();
private final Map aliases;
private final Map> customReaders;
public DynamicCsvMapper(final Class target, final ReflectionService reflectionService,
final FieldMapperErrorHandler fieldMapperErrorHandler,
final MapperBuilderErrorHandler mapperBuilderErrorHandler, String defaultDateFormat,
Map aliases, Map> customReaders) {
this.classMeta = reflectionService.getClassMeta(target);
this.target = target;
this.fieldMapperErrorHandler = fieldMapperErrorHandler;
this.mapperBuilderErrorHandler = mapperBuilderErrorHandler;
this.csvParser = new CsvParser();
this.defaultDateFormat = defaultDateFormat;
this.aliases = aliases;
this.customReaders = customReaders;
}
@Override
public > H forEach(final Reader reader, final H handler) throws IOException, MappingException {
return forEach(reader, handler, 0, -1);
}
@Override
public > H forEach(final Reader reader, final H handler, final int rowStart) throws IOException, MappingException {
return forEach(reader, handler, rowStart, -1);
}
@Override
public > H forEach(final Reader reader, final H handler, final int rowStart, final int limit) throws IOException, MappingException {
csvParser.parse(reader, new DynamicCellHandler(handler, rowStart, limit));
return handler;
}
private CsvMapperImpl buildeMapper(MapperKey key) {
CsvMapperBuilder builder = new CsvMapperBuilder(target, classMeta, aliases, customReaders);
builder.fieldMapperErrorHandler(fieldMapperErrorHandler);
builder.mapperBuilderErrorHandler(mapperBuilderErrorHandler);
builder.setDefaultDateFormat(defaultDateFormat);
for(String col : key.getColumns()) {
builder.addMapping(col);
}
return (CsvMapperImpl)builder.mapper();
}
@Override
public > H forEach(InputStream is, H handle)
throws IOException, MappingException {
return forEach(new InputStreamReader(is), handle);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy