Skip to content

Commit 791a64c

Browse files
Appendium#36 Started with RFC4180 compliance
1 parent 51d35dd commit 791a64c

File tree

6 files changed

+201
-3
lines changed

6 files changed

+201
-3
lines changed

flatpack/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
<dependency>
140140
<groupId>junit</groupId>
141141
<artifactId>junit</artifactId>
142-
<version>3.8.2</version>
142+
<version>4.12</version>
143143
<scope>test</scope>
144144
</dependency>
145145
<dependency>

flatpack/src/main/java/net/sf/flatpack/writer/AbstractWriter.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@
1212
public abstract class AbstractWriter implements Writer {
1313
private final BufferedWriter writer;
1414
private Map<String, Object> rowMap;
15+
protected String lineSeperator = System.lineSeparator();
1516

1617
public AbstractWriter(final java.io.Writer output) {
1718
super();
1819
writer = new BufferedWriter(output);
1920
}
2021

22+
public AbstractWriter(final java.io.Writer writer, final String lineSeperator) {
23+
super();
24+
this.writer = new BufferedWriter(writer);
25+
this.lineSeperator = lineSeperator;
26+
}
27+
2128
@Override
2229
public Writer addRecordEntry(final String columnName, final Object value) {
2330
if (rowMap == null) {
@@ -53,7 +60,7 @@ public Writer nextRecord() throws IOException {
5360
// the row should have been written out by the subclass so it's safe to
5461
// discard it here
5562
rowMap = null;
56-
writer.newLine();
63+
writer.write(this.lineSeperator);
5764
return this;
5865
}
5966

flatpack/src/main/java/net/sf/flatpack/writer/DelimiterWriter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ protected DelimiterWriter(final Map columnMapping, final java.io.Writer output,
2626
super(output);
2727
this.delimiter = delimiter;
2828
this.qualifier = qualifier;
29+
this.lineSeperator = options.getLineSeperator();
2930

30-
columnTitles = new ArrayList<String>();
31+
columnTitles = new ArrayList<>();
3132
final List<ColumnMetaData> columns = (List<ColumnMetaData>) columnMapping.get(FPConstants.DETAIL_ID);
3233
for (final ColumnMetaData cmd : columns) {
3334
columnTitles.add(cmd.getColName());

flatpack/src/main/java/net/sf/flatpack/writer/WriterOptions.java

+18
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
public class WriterOptions {
99

1010
private boolean autoPrintHeader = true;
11+
private String lineSeperator = System.lineSeparator();
1112

1213
/**
1314
* Returns a DelimiterWriterOptions instance
@@ -36,4 +37,21 @@ public WriterOptions autoPrintHeader(final boolean autoPrintHeader) {
3637
return this;
3738
}
3839

40+
/**
41+
* Get the current line separator. Default is the system line separator.
42+
* @return
43+
*/
44+
public String getLineSeperator() {
45+
return lineSeperator;
46+
}
47+
48+
/**
49+
* Set the line leperator.
50+
* @param lineSeperator the line seperator
51+
* @return
52+
*/
53+
public WriterOptions setLineSeperator(String lineSeperator) {
54+
this.lineSeperator = lineSeperator;
55+
return this;
56+
}
3957
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package net.sf.flatpack.rfc4180;
2+
3+
import java.io.IOException;
4+
import java.io.StringWriter;
5+
6+
import net.sf.flatpack.writer.DelimiterWriterFactory;
7+
import net.sf.flatpack.writer.Rfc4180TestCase;
8+
import net.sf.flatpack.writer.Writer;
9+
import net.sf.flatpack.writer.WriterOptions;
10+
11+
import static org.hamcrest.CoreMatchers.is;
12+
import static org.hamcrest.CoreMatchers.not;
13+
import static org.hamcrest.CoreMatchers.notNullValue;
14+
import static org.junit.Assert.assertThat;
15+
16+
public class CsvWriterFormatDefintionTest extends Rfc4180TestCase {
17+
private final char FIELD_DELIMITER = ',';
18+
private final char FIELD_QUALIFIER = '"';
19+
private final String LINE_SEPERATOR = "\r\n";
20+
21+
22+
/*
23+
* 2.1 Each record is located on a separate line, delimited by a line break (CRLF). For example:
24+
*
25+
* aaa,bbb,ccc CRLF
26+
* zzz,yyy,xxx CRLF
27+
*/
28+
public void testLineSeparation() throws IOException {
29+
final StringWriter out = new StringWriter();
30+
31+
try (Writer writer = getWriterForRfc4180(out, false)) {
32+
// write one line of data ... not in the correct order of fields
33+
writer.addRecordEntry("col1", "aaa")
34+
.addRecordEntry("col2", "bbb")
35+
.addRecordEntry("col3", "ccc")
36+
.nextRecord();
37+
writer.addRecordEntry("col3", "xxx")
38+
.addRecordEntry("col2", "yyy")
39+
.addRecordEntry("col1", "zzz")
40+
.nextRecord();
41+
42+
writer.flush();
43+
}
44+
45+
String result = out.toString();
46+
assertThat(result, is(notNullValue()));
47+
assertThat(result.length(), is(26));
48+
49+
String[] lines = result.split(LINE_SEPERATOR);
50+
assertThat(lines, is(notNullValue()));
51+
assertThat(lines.length, is(2));
52+
assertThat(lines[0], is("aaa,bbb,ccc"));
53+
assertThat(lines[1], is("zzz,yyy,xxx"));
54+
}
55+
56+
/*
57+
* 2.4a. Each line should contain the same number of fields throughout the file
58+
*/
59+
public void testSameNumberOffFields() throws IOException {
60+
final StringWriter out = new StringWriter();
61+
62+
try (Writer writer = getWriterForRfc4180(out, false)) {
63+
// write one line of data ... not in the correct order of fields
64+
writer.addRecordEntry("col1", "aaa")
65+
.addRecordEntry("col2", "bbb")
66+
.addRecordEntry("col3", "ccc")
67+
.nextRecord();
68+
writer.addRecordEntry("col3", "xxx")
69+
//.addRecordEntry("col2", "yyy")
70+
.addRecordEntry("col1", "zzz")
71+
.nextRecord();
72+
73+
writer.flush();
74+
}
75+
76+
String result = out.toString();
77+
assertThat(result, is(notNullValue()));
78+
assertThat(result.length(), is(23));
79+
80+
String[] lines = result.split(LINE_SEPERATOR);
81+
assertThat(lines, is(notNullValue()));
82+
assertThat(lines.length, is(2));
83+
assertThat(lines[0], is("aaa,bbb,ccc"));
84+
assertThat(lines[0].split(String.valueOf(FIELD_DELIMITER)).length, is(3));
85+
assertThat(lines[1], is("zzz,,xxx"));
86+
assertThat(lines[1].split(String.valueOf(FIELD_DELIMITER)).length, is(3));
87+
}
88+
89+
/*
90+
* 2.4b. Spaces are considered part of a field and should not be ignored.
91+
*/
92+
public void testSpacesArePartOfField() throws IOException {
93+
final StringWriter out = new StringWriter();
94+
95+
try (Writer writer = getWriterForRfc4180(out, false)) {
96+
// write one line of data ... not in the correct order of fields
97+
writer.addRecordEntry("col1", "aaa ")
98+
.addRecordEntry("col2", " bbb")
99+
.addRecordEntry("col3", "c cc")
100+
.nextRecord();
101+
writer.addRecordEntry("col3", "x x x")
102+
.addRecordEntry("col2", "yy y")
103+
.addRecordEntry("col1", " zzz ")
104+
.nextRecord();
105+
106+
writer.flush();
107+
}
108+
109+
String result = out.toString();
110+
assertThat(result, is(notNullValue()));
111+
assertThat(result.length(), is(34));
112+
113+
String[] lines = result.split(LINE_SEPERATOR);
114+
assertThat(lines, is(notNullValue()));
115+
assertThat(lines.length, is(2));
116+
assertThat(lines[0], is("aaa , bbb,c cc"));
117+
assertThat(lines[1], is(" zzz ,yy y,x x x"));
118+
}
119+
120+
/*
121+
* 2.4c. The last field in the record must not be followed by a comma
122+
*/
123+
public void testLastFieldShouldNotHaveDelimiter() throws IOException {
124+
final StringWriter out = new StringWriter();
125+
126+
try (Writer writer = getWriterForRfc4180(out, false)) {
127+
// write one line of data ... not in the correct order of fields
128+
writer.addRecordEntry("col1", "aaa")
129+
.addRecordEntry("col2", "bbb")
130+
.addRecordEntry("col3", "ccc")
131+
.nextRecord();
132+
writer.addRecordEntry("col3", "xxx")
133+
.addRecordEntry("col2", "yyy")
134+
.addRecordEntry("col1", "zzz")
135+
.nextRecord();
136+
137+
writer.flush();
138+
}
139+
140+
String result = out.toString();
141+
assertThat(result, is(notNullValue()));
142+
assertThat(result.length(), is(26));
143+
144+
String[] lines = result.split(LINE_SEPERATOR);
145+
assertThat(lines, is(notNullValue()));
146+
assertThat(lines.length, is(2));
147+
assertThat(lines[0].length(), is(11));
148+
assertThat(lines[0].charAt(lines[0].length() -1), is(not(FIELD_DELIMITER)));
149+
assertThat(lines[1].length(), is(11));
150+
assertThat(lines[1].charAt(lines[0].length() -1), is(not(FIELD_DELIMITER)));
151+
}
152+
153+
154+
private Writer getWriterForRfc4180(java.io.Writer out, boolean autoPrintHeader) throws IOException {
155+
WriterOptions options = WriterOptions.getInstance();
156+
options.autoPrintHeader(autoPrintHeader);
157+
options.setLineSeperator(LINE_SEPERATOR);
158+
159+
final DelimiterWriterFactory factory = new DelimiterWriterFactory(FIELD_DELIMITER, FIELD_QUALIFIER)//
160+
.addColumnTitle("col1")
161+
.addColumnTitle("col2")
162+
.addColumnTitle("col3");
163+
164+
return factory.createWriter(out, options);
165+
}
166+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package net.sf.flatpack.writer;
2+
3+
import junit.framework.TestCase;
4+
5+
public abstract class Rfc4180TestCase extends TestCase {
6+
}

0 commit comments

Comments
 (0)