some options for our poor CSV generator

This commit is contained in:
Jörg Prante 2022-06-22 16:51:19 +02:00
parent 50b94ef8b2
commit 52bdcb641f
3 changed files with 43 additions and 9 deletions

View file

@ -8,6 +8,5 @@ public interface Constants {
char LF = '\n'; char LF = '\n';
char TAB = '\t'; char TAB = '\t';
char COMMA = ','; char COMMA = ',';
char QUOTE = '\"'; char DOUBLE_QUOTE = '\"';
char ESCAPE_CHARACTER = '\"';
} }

View file

@ -19,12 +19,33 @@ public class Generator implements Constants, Closeable, Flushable {
private List<String> keys; private List<String> keys;
private char separator = COMMA;
private char quote = DOUBLE_QUOTE;
private boolean alwaysQuote;
public Generator(Writer writer) { public Generator(Writer writer) {
this.writer = writer; this.writer = writer;
this.col = 0; this.col = 0;
this.keys = new ArrayList<>(); this.keys = new ArrayList<>();
} }
public Generator setSeparator(char separator) {
this.separator = separator;
return this;
}
public Generator setAlwaysQuote(boolean alwaysQuote) {
this.alwaysQuote = alwaysQuote;
return this;
}
public Generator setQuote(char quote) {
this.quote = quote;
return this;
}
public Generator keys(List<String> keys) { public Generator keys(List<String> keys) {
this.keys = keys; this.keys = keys;
return this; return this;
@ -44,7 +65,7 @@ public class Generator implements Constants, Closeable, Flushable {
col = 0; col = 0;
} else { } else {
if (col > 0) { if (col > 0) {
writer.write(COMMA); writer.write(separator);
} }
} }
if (value != null) { if (value != null) {
@ -72,8 +93,7 @@ public class Generator implements Constants, Closeable, Flushable {
} }
private String escape(String value) { private String escape(String value) {
if (value.indexOf(QUOTE) < 0 if (!alwaysQuote && value.indexOf(quote) < 0
&& value.indexOf(ESCAPE_CHARACTER) < 0
&& value.indexOf(COMMA) < 0 && value.indexOf(COMMA) < 0
&& value.indexOf(TAB) < 0 && value.indexOf(TAB) < 0
&& !value.contains(LF)) { && !value.contains(LF)) {
@ -81,15 +101,15 @@ public class Generator implements Constants, Closeable, Flushable {
} }
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);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char ch = value.charAt(i); char ch = value.charAt(i);
if (ch == QUOTE) { if (ch == quote) {
sb.append(QUOTE); sb.append(quote);
} }
sb.append(ch); sb.append(ch);
} }
sb.append(QUOTE); sb.append(quote);
return sb.toString(); return sb.toString();
} }

View file

@ -47,4 +47,19 @@ public class GeneratorTest {
gen.close(); gen.close();
assertEquals("val0,\"\"\"Hello, World\"\"\",\"hey look a line seperator \n\"", writer.toString()); assertEquals("val0,\"\"\"Hello, World\"\"\",\"hey look a line seperator \n\"", writer.toString());
} }
@Test
public void testSemicolonAlwaysQuote() throws IOException {
StringWriter writer = new StringWriter();
Generator gen = new Generator(writer).setAlwaysQuote(true).setSeparator(';');
gen.keys(Arrays.asList("a", "b", "c"));
for (int i = 0; i < 1; i++) {
gen.write("val" + i);
gen.write("\"Hello, World\"");
gen.write("hey look a line seperator \n");
}
gen.close();
assertEquals("\"val0\";\"\"\"Hello, World\"\"\";\"hey look a line seperator \n\"", writer.toString());
}
} }