package com.revolsys.record.io.format.csv; import java.io.BufferedWriter; import java.io.IOException; import java.io.Writer; import java.nio.file.Path; import com.revolsys.datatype.DataType; import com.revolsys.geometry.cs.esri.EsriCoordinateSystems; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.io.AbstractRecordWriter; import com.revolsys.record.Record; import com.revolsys.record.io.format.wkt.EWktWriter; import com.revolsys.record.schema.FieldDefinition; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.spring.resource.PathResource; import com.revolsys.spring.resource.Resource; import com.revolsys.util.Exceptions; public class CsvRecordWriter extends AbstractRecordWriter { private final boolean ewkt; private final char fieldSeparator; /** The writer */ private Writer out; private final RecordDefinition recordDefinition; private final boolean useQuotes; public CsvRecordWriter(final RecordDefinition recordDefinition, final Path path, final char fieldSeparator, final boolean useQuotes, final boolean ewkt) { this(recordDefinition, new PathResource(path), fieldSeparator, useQuotes, ewkt); } public CsvRecordWriter(final RecordDefinition recordDefinition, final Resource resource, final char fieldSeparator, final boolean useQuotes, final boolean ewkt) { this(recordDefinition, resource.newWriter(), fieldSeparator, useQuotes, ewkt); setResource(resource); final GeometryFactory geometryFactory = recordDefinition.getGeometryFactory(); EsriCoordinateSystems.writePrjFile(resource, geometryFactory); } public CsvRecordWriter(final RecordDefinition recordDefinition, final Writer out, final char fieldSeparator, final boolean useQuotes, final boolean ewkt) { try { this.recordDefinition = recordDefinition; this.out = new BufferedWriter(out); this.fieldSeparator = fieldSeparator; this.useQuotes = useQuotes; this.ewkt = ewkt; for (int i = 0; i < recordDefinition.getFieldCount(); i++) { if (i > 0) { this.out.write(fieldSeparator); } final String name = recordDefinition.getFieldName(i); string(name); } this.out.write('\n'); } catch (final IOException e) { throw Exceptions.wrap(e); } } /** * Closes the underlying reader. */ @Override public synchronized void close() { final Writer out = this.out; if (out != null) { try { out.close(); } catch (final IOException e) { } this.out = null; } } @Override public synchronized void flush() { if (this.out != null) { try { this.out.flush(); } catch (final IOException e) { throw Exceptions.wrap(e); } } } @Override public RecordDefinition getRecordDefinition() { return this.recordDefinition; } private void string(final Object value) throws IOException { final Writer out = this.out; if (out != null) { final String string = value.toString(); if (this.useQuotes) { out.write('"'); for (int i = 0; i < string.length(); i++) { final char c = string.charAt(i); if (c == '"') { out.write('"'); } out.write(c); } out.write('"'); } else { out.write(string, 0, string.length()); } } } @Override public void write(final Record record) { final Writer out = this.out; if (out != null) { try { final RecordDefinition recordDefinition = this.recordDefinition; final char fieldSeparator = this.fieldSeparator; boolean first = true; for (final FieldDefinition field : recordDefinition.getFields()) { if (first) { first = false; } else { out.write(fieldSeparator); } final String fieldName = field.getName(); final Object value; if (isWriteCodeValues()) { value = record.getCodeValue(fieldName); } else { value = record.getValue(fieldName); } if (value instanceof Geometry) { final Geometry geometry = (Geometry)value; final String text = EWktWriter.toString(geometry, this.ewkt); string(text); } else if (value != null) { final DataType dataType = field.getDataType(); final String stringValue = dataType.toString(value); if (dataType.isRequiresQuotes()) { string(stringValue); } else { out.write(stringValue, 0, stringValue.length()); } } } out.write('\n'); } catch (final IOException e) { throw Exceptions.wrap(e); } } } }