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

com.github.skjolber.stcsv.CsvMapper Maven / Gradle / Ivy

There is a newer version: 1.0.25
Show newest version
package com.github.skjolber.stcsv;

import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.objectweb.asm.MethodVisitor;

import com.github.skjolber.stcsv.builder.CsvBuilderException;
import com.github.skjolber.stcsv.builder.CsvMappingBuilder;

/**
 * 
 * Dynamic CSV parser generator. Adapts the underlying implementation according 
 * to the first (header) line.
 * 

* Uses ASM to build the parsers. *

* Thread-safe. */ public class CsvMapper extends AbstractCsvMapper { protected final Map> factories = new ConcurrentHashMap<>(); public static CsvMappingBuilder builder(Class cls) { return new CsvMappingBuilder(cls); } public CsvMapper(Class cls, char divider, char quoteCharacter, char escapeCharacter, List columns, boolean skipEmptyLines, boolean skipComments, boolean skippableFieldsWithoutLinebreaks, ClassLoader classLoader, int bufferLength) { super(cls, divider, quoteCharacter, escapeCharacter, columns, skipEmptyLines, skipComments, skippableFieldsWithoutLinebreaks, classLoader, bufferLength); } public CsvReader create(Reader reader) throws Exception { // avoid multiple calls to read when locating the first line // so read a full buffer char[] current = new char[bufferLength + 1]; int start = 0; int end = 0; do { int read = reader.read(current, start, bufferLength - start); if(read == -1) { return new EmptyCsvReader<>(); } else { end += read; } for(int i = start; i < end; i++) { if(current[i] == '\n') { return create(reader, new String(current, 0, i), current, i + 1, end); } } start += end; } while(end < bufferLength); throw new CsvException("No linebreak found in " + current.length + " characters"); } public CsvReader create(Reader reader, String header, char[] current, int offset, int length) throws Exception { StaticCsvMapper constructor = factories.get(header); // note: using the stringbuilder as a key does not work if(constructor == null) { boolean carriageReturns = header.length() > 1 && header.charAt(header.length() - 1) == '\r'; List fields = parseColumnNames(header); constructor = buildStaticCsvMapper(carriageReturns, fields); if(constructor == null) { return new EmptyCsvReader<>(); } factories.put(header, constructor); } return constructor.newInstance(reader, current, offset, length); } // TODO builder pattern @SuppressWarnings({ "rawtypes", "unchecked" }) public StaticCsvMapper buildDefaultStaticCsvMapper(boolean carriageReturns) throws Exception { return new DefaultStaticCsvMapper(super.createDefaultReaderClass(carriageReturns)); } @SuppressWarnings({ "rawtypes", "unchecked" }) public StaticCsvMapper buildStaticCsvMapper(String firstLine) throws Exception { boolean carriageReturns = firstLine.charAt(firstLine.length() - 2) == '\r'; String line; if(carriageReturns) { line = firstLine.substring(0, firstLine.length() - 2); } else { line = firstLine.substring(0, firstLine.length() - 1); } return new DefaultStaticCsvMapper(super.createReaderClass(carriageReturns, line)); } @SuppressWarnings({ "rawtypes", "unchecked" }) public StaticCsvMapper buildStaticCsvMapper(boolean carriageReturns, String header) throws Exception { return new DefaultStaticCsvMapper(super.createReaderClass(carriageReturns, header)); } @SuppressWarnings({ "rawtypes", "unchecked" }) public StaticCsvMapper buildStaticCsvMapper(boolean carriageReturns, List csvFileFieldNames) throws Exception { return new DefaultStaticCsvMapper(super.createReaderClass(carriageReturns, csvFileFieldNames)); } @Override protected void writeTriConsumerVariable(String subClassInternalName, MethodVisitor mv) { throw new CsvBuilderException(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy