fix for forced unquoted tabulator-separated csv writing
This commit is contained in:
parent
e1e9a35cd7
commit
fdd791dcd5
1 changed files with 35 additions and 12 deletions
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
|
|
||||||
public class Generator implements Constants, Closeable, Flushable {
|
public class Generator implements Constants, Closeable, Flushable {
|
||||||
|
|
||||||
private static final String LF = System.getProperty("line.separator");
|
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||||
|
|
||||||
private final Writer writer;
|
private final Writer writer;
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ public class Generator implements Constants, Closeable, Flushable {
|
||||||
|
|
||||||
private boolean alwaysQuote;
|
private boolean alwaysQuote;
|
||||||
|
|
||||||
|
private boolean neverQuote;
|
||||||
|
|
||||||
public Generator(Writer writer) {
|
public Generator(Writer writer) {
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
this.col = 0;
|
this.col = 0;
|
||||||
|
@ -41,6 +43,11 @@ public class Generator implements Constants, Closeable, Flushable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Generator setNeverQuote(boolean neverQuote) {
|
||||||
|
this.neverQuote = neverQuote;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Generator setQuote(char quote) {
|
public Generator setQuote(char quote) {
|
||||||
this.quote = quote;
|
this.quote = quote;
|
||||||
return this;
|
return this;
|
||||||
|
@ -59,15 +66,16 @@ public class Generator implements Constants, Closeable, Flushable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void write(String value) throws IOException {
|
public synchronized void write(String value) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
throw new IllegalArgumentException("null value not allowed");
|
||||||
|
}
|
||||||
if (col > 0) {
|
if (col > 0) {
|
||||||
writer.write(separator);
|
writer.write(separator);
|
||||||
}
|
}
|
||||||
if (value != null) {
|
writer.write(maybeEscape(value));
|
||||||
writer.write(escape(value));
|
|
||||||
}
|
|
||||||
col++;
|
col++;
|
||||||
if (col >= keys.size()) {
|
if (col >= keys.size()) {
|
||||||
writer.write(LF);
|
writer.write(LINE_SEPARATOR);
|
||||||
row++;
|
row++;
|
||||||
col = 0;
|
col = 0;
|
||||||
}
|
}
|
||||||
|
@ -91,13 +99,29 @@ public class Generator implements Constants, Closeable, Flushable {
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String escape(String value) {
|
private String maybeEscape(String value) {
|
||||||
if (!alwaysQuote && value.indexOf(quote) < 0
|
if (alwaysQuote) {
|
||||||
&& value.indexOf(COMMA) < 0
|
return escape(value);
|
||||||
&& value.indexOf(TAB) < 0
|
|
||||||
&& !value.contains(LF)) {
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
if (neverQuote) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value.indexOf(quote) < 0
|
||||||
|
&& value.indexOf(separator) < 0
|
||||||
|
&& value.indexOf(TAB) < 0
|
||||||
|
&& value.indexOf(FF) < 0
|
||||||
|
&& value.indexOf(CR) < 0
|
||||||
|
&& value.indexOf(LF) < 0
|
||||||
|
&& value.indexOf(BACKSPACE) < 0
|
||||||
|
&& !value.contains(LINE_SEPARATOR)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return escape(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String escape(String value) {
|
||||||
|
// escape means, surround the value by the quote character and emit quote character with the value twice
|
||||||
int length = value.length();
|
int length = value.length();
|
||||||
StringBuilder sb = new StringBuilder(length + 2);
|
StringBuilder sb = new StringBuilder(length + 2);
|
||||||
sb.append(quote);
|
sb.append(quote);
|
||||||
|
@ -111,5 +135,4 @@ public class Generator implements Constants, Closeable, Flushable {
|
||||||
sb.append(quote);
|
sb.append(quote);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue