CsvParser implements Serializable { public List<String> parse(final String row) throws Exception { this.tokens.clear(); int scanOffset = 0; while (scanOffset <= row.length()) { scanOffset = readNextField(row, scanOffset); if (this.nullString != null) { final int lastIndex = this.tokens.size() - 1; String lastToken = this.tokens.get(lastIndex); if (this.nullString.equals(lastToken)) { this.tokens.set(lastIndex, null); } } } if (this.numExpectedFields >= 0) { final int numEncounteredFields = this.tokens.size(); if (numEncounteredFields != this.numExpectedFields) { final String msg = String.format("Found %d field, expected %d: <<<%s>>>", numEncounteredFields, this.numExpectedFields, row); if (this.lenientPolicy == FAIL_ON_ILLEGAL_LINES || (this.lenientPolicy == FAIL_ON_OVERLONG_LINES && numEncounteredFields > this.numExpectedFields)) { throw new RuntimeException(msg); } else { logger.warn(msg); } } } return this.tokens; } CsvParser(final char fieldSeparator, final char quoteChar, final String nullString);  CsvParser(final char fieldSeparator, final char quoteChar, final String nullString, final int numExpectedFields,
                     final int lenientPolicy); List<String> parse(final String row); void setNumExpectedFields(int numExpectedFields); static final int FAIL_ON_ILLEGAL_LINES; static final int FAIL_ON_OVERLONG_LINES; static final int WARN_ON_ILLEGAL_LINES; }
@Test public void testSimpleParsing() throws Exception { String line; final CsvParser parser = new CsvParser(',', '\"', null); line = "\"a\"," + "\"bba\"," + "," + "\"a,b,c\""; final List<String> expectation = Arrays.asList("a", "bba", "", "a,b,c"); final List<String> result = parser.parse(line); Assert.assertEquals(expectation, result); }
@Test public void testParsingMoreThanOnce() throws Exception { String line; List<String> expectation; List<String> result; final CsvParser parser = new CsvParser(',', '\0', null); line = "1,2,3,4"; expectation = Arrays.asList("1,2,3,4".split(",")); result = parser.parse(line); Assert.assertEquals(expectation, result); line = "1,2,3,4,5"; expectation = Arrays.asList("1,2,3,4,5".split(",")); result = parser.parse(line); Assert.assertEquals(expectation, result); line = "1,2"; expectation = Arrays.asList("1,2".split(",")); result = parser.parse(line); Assert.assertEquals(expectation, result); }
@Test public void splittingEasyLinesShouldWork() throws Exception { CsvParser parser = new CsvParser(';', '"', null); String testRow = "\"Hello\";;\"World;\";\"\";!;\"\""; List<String> expectedResult = Arrays.asList("Hello", "", "World;", "", "!", ""); List<String> result = parser.parse(testRow); Assert.assertEquals(expectedResult, result); }
@Test public void twoConsequentQuotesShouldBeEscaped() throws Exception { CsvParser parser = new CsvParser(';', '"', null); String testRow = "\"Hello \"\"World\"\"\";" + "\"\"\";\"\"\";" + "\"\"\"World\"\"\";" + "\"\"\"\";" + "\"\"\"\"\"\";" + "\"\";" + "\"\""; List<String> expectedResult = Arrays.asList("Hello \"World\"", "\";\"", "\"World\"", "\"", "\"\"", "", ""); List<String> result = parser.parse(testRow); Assert.assertEquals(expectedResult, result); }
@Test public void emptyNullStringShouldWork() throws Exception { CsvParser parser = new CsvParser(';', '"', ""); String testRow = "null;\"\";;\"\""; List<String> expectedResult = Arrays.asList("null", null, null, null); List<String> result = parser.parse(testRow); Assert.assertEquals(expectedResult, result); }
@Test public void nonEmptyNullStringShouldWork() throws Exception { CsvParser parser = new CsvParser(';', '"', "\\N"); String testRow = "null;\"\\N\";\\N"; List<String> expectedResult = Arrays.asList("null", null, null); List<String> result = parser.parse(testRow); Assert.assertEquals(expectedResult, result); }