package com.emc.ecs.sync.rest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.text.DateFormat; import java.text.SimpleDateFormat; public abstract class AbstractCsvWriter<T> implements Runnable { private static final Logger log = LoggerFactory.getLogger(ErrorReportWriter.class); public static final int BUFFER_SIZE = 128 * 1024; public static final String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss z"; private Iterable<T> records; private PipedInputStream readStream; private Writer writer; protected DateFormat formatter = new SimpleDateFormat(DATE_FORMAT); public AbstractCsvWriter(Iterable<T> records) throws IOException { this.records = records; this.readStream = new PipedInputStream(BUFFER_SIZE); this.writer = new OutputStreamWriter(new PipedOutputStream(readStream)); } protected abstract String[] getHeaders(); protected abstract Object[] getColumns(T record); @Override public void run() { try { // header writeCsvRow((Object[]) getHeaders()); // rows for (T record : records) { writeCsvRow((Object[]) getColumns(record)); } writer.flush(); writer.close(); } catch (IOException e) { // don't close the stream, so the read end will get an exception and know there was a problem log.warn("Exception in stream writer!", e); } } private void writeCsvRow(Object... values) throws IOException { for (int i = 0; i < values.length; i++) { if (i > 0) writer.write(","); if (values[i] != null) writer.write("\"" + escape(values[i].toString()) + "\""); } writer.write("\n"); } private String escape(String value) { return value.replace("\"", "\"\""); } public InputStream getReadStream() { return readStream; } }