com.threewks.thundr.csv.BeanToCsvStreamer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of thundr-contrib-csv Show documentation
Show all versions of thundr-contrib-csv Show documentation
A thundr module for working with csvs
The newest version!
/*
* This file is a component of thundr, a software library from 3wks.
* Read more: http://3wks.github.io/thundr/
* Copyright (C) 2014 3wks,
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.threewks.thundr.csv;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.opencsv.CSVWriter;
import com.opencsv.bean.BeanToCsv;
import com.opencsv.bean.MappingStrategy;
import com.threewks.thundr.exception.BaseException;
import com.threewks.thundr.transformer.TransformerManager;
/**
* An implementation of BeanToCsv which can handle streaming results to minimise memory footprint.
*
* @param
*/
public class BeanToCsvStreamer extends BeanToCsv {
private static final int DefaultBatchSize = 1000;
protected int batchSize;
private TransformerManager transformerManager;
public BeanToCsvStreamer(TransformerManager transformerManager) {
this(transformerManager, DefaultBatchSize);
}
public BeanToCsvStreamer(TransformerManager transformerManager, int batchSize) {
this.transformerManager = transformerManager;
this.batchSize = Math.max(batchSize, 1);
}
public BeanToCsvStreamer withBatchSize(int batchSize) {
this.batchSize = Math.max(batchSize, 1);
return this;
}
public int getBatchSize() {
return batchSize;
}
public boolean write(MappingStrategy mapper, CSVWriter csv, Iterable objects, boolean includeHeader) {
if (objects == null) {
return false;
}
Iterator iterator = objects.iterator();
if (!iterator.hasNext()) {
return false;
}
try {
List getters = findGetters(mapper);
if (includeHeader) {
writeHeader(mapper, csv);
}
List batch = batch(iterator, batchSize);
while (batch.size() > 0) {
processAndWriteObjects(csv, batch, getters);
batch = batch(iterator, batchSize);
}
return true;
} catch (Exception e) {
throw new RuntimeException("Error writing CSV !", e);
}
}
public void writeHeader(MappingStrategy mapper, CSVWriter csv) {
try {
csv.writeNext(processHeader(mapper));
} catch (Exception e) {
throw new BaseException(e);
}
}
public boolean write(MappingStrategy mapper, CSVWriter csv, Iterable objects) {
return this.write(mapper, csv, objects, true);
}
private List batch(Iterator iterator, int size) {
List batch = new ArrayList<>();
for (int i = 0; i < size && iterator.hasNext(); i++) {
batch.add(iterator.next());
}
return batch;
}
/**
* Build getters list from provided mapper.
*
* @param mapper MappingStrategy for Bean
* @return - list of methods for getting the data in the bean.
* @throws IntrospectionException - thrown if there is an failure in Introspection.
*/
protected List findGetters(MappingStrategy mapper) throws IntrospectionException {
int i = 0;
PropertyDescriptor prop = mapper.findDescriptor(i);
// build getters methods list
List readers = new ArrayList();
while (prop != null) {
readers.add(prop.getReadMethod());
i++;
prop = mapper.findDescriptor(i);
}
return readers;
}
/**
* Processes a list of objects.
*
* @param csv - csvWriter
* @param objects - list of objects to process
* @param getters - list of getter methods to retrieve the data from the objects.
* @throws IntrospectionException - thrown if there is an failure in Introspection.
* @throws IllegalAccessException - thrown if there is an failure in Introspection.
* @throws InvocationTargetException - thrown if there is an failure in Introspection.
*/
protected void processAndWriteObjects(CSVWriter csv, List objects, List getters) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
for (Object obj : objects) {
String[] line = processObject(getters, obj);
csv.writeNext(line);
}
}
/**
* Retrieve all the information out of an object.
*
* @param getters - List of methods to retrieve information.
* @param bean - object to get the information from.
* @return String array containing the information from the object
* @throws IntrospectionException - thrown by error in introspection.
* @throws IllegalAccessException - thrown by error in introspection.
* @throws InvocationTargetException - thrown by error in introspection.
*/
@Override
protected String[] processObject(List getters, Object bean) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
String[] results = new String[getters.size()];
for (int i = 0; i < getters.size(); i++) {
Method getter = getters.get(i);
Object value = getter.invoke(bean, (Object[]) null);
Class