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

com.github.gv2011.util.csv.DefaultCsvEngine Maven / Gradle / Ivy

The newest version!
package com.github.gv2011.util.csv;

import static com.github.gv2011.util.ex.Exceptions.call;
import static com.github.gv2011.util.icol.ICollections.toIList;
import static com.github.gv2011.util.icol.ICollections.toIMap;

import java.io.Reader;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Stream;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import com.github.gv2011.util.BeanUtils;
import com.github.gv2011.util.CsvUtils.CsvEngine;
import com.github.gv2011.util.CsvUtils.CsvFormat;
import com.github.gv2011.util.XStream;
import com.github.gv2011.util.beans.BeanBuilder;
import com.github.gv2011.util.beans.BeanType;
import com.github.gv2011.util.beans.ExtendedBeanBuilder;
import com.github.gv2011.util.beans.Property;
import com.github.gv2011.util.bytes.Bytes;
import com.github.gv2011.util.icol.IList;
import com.github.gv2011.util.icol.IMap;

public class DefaultCsvEngine implements CsvEngine{

  @Override
  public  IList read(final Bytes csvFile, final CsvFormat format, final Class beanClass) {
    return stream(csvFile, format, beanClass).collect(toIList());
  }

  private  Stream stream(final Bytes csvFile, final CsvFormat format, final Class beanClass) {
    final Function converter = createConverter(format, beanClass);
    final Reader csv = csvFile.reader();
    return XStream
      .fromIterator(
        call(()->new CSVParser(csv, convertFormat(format)))
        .iterator()
      )
      .onClose(()->call(csv::close))
      .map(converter)
    ;
  }

  private  Function createConverter(final CsvFormat format, final Class beanClass) {
    final BeanType beanType = BeanUtils.typeRegistry().beanType(beanClass);
    final IMap> propsByColumns = beanType.properties().entrySet().stream().collect(toIMap(
        e->format.getColumnName(e.getKey()),
        Entry::getValue
    ));
    return r->{
      final ExtendedBeanBuilder builder = beanType.createBuilder();
      propsByColumns.forEach((c,p)->{
        set(builder, p, r.get(c));
      });
      return builder.build();
    };
  }

  private  void set(final BeanBuilder builder, final Property p, final String s){
    builder.set(p, p.type().parse(s));
  }

  private CSVFormat convertFormat(final CsvFormat format) {
  	return CSVFormat.Builder
  		.create(CSVFormat.RFC4180)
  		.setDelimiter(';')
  		.setQuote('"')
  		.setRecordSeparator("\r\n")
  		.setHeader().setSkipHeaderRecord(true)
  		.build()
  	;
  }

}