Author: ggregory Date: Sat Oct 13 17:09:48 2012 New Revision: 1397895 URL: http://svn.apache.org/viewvc?rev=1397895&view=rev Log: [CSV-52] Keep track of record numbers.
Modified: commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVRecord.java commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java Modified: commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java?rev=1397895&r1=1397894&r2=1397895&view=diff ============================================================================== --- commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java (original) +++ commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java Sat Oct 13 17:09:48 2012 @@ -70,6 +70,7 @@ public class CSVParser implements Iterab private final Lexer lexer; private final Map<String, Integer> headerMap; + private long recordNumber; // the following objects are shared to reduce garbage @@ -134,7 +135,7 @@ public class CSVParser implements Iterab /** * Returns the current line number in the input stream. * <p/> - * ATTENTION: If your CSV input has multiline-values, the returned number does not correspond to the record-number. + * ATTENTION: If your CSV input has multi-line values, the returned number does not correspond to the record number. * * @return current line number */ @@ -143,6 +144,17 @@ public class CSVParser implements Iterab } /** + * Returns the current record number in the input stream. + * <p/> + * ATTENTION: If your CSV input has multi-line values, the returned number does not correspond to the line number. + * + * @return current line number + */ + public long getRecordNumber() { + return recordNumber; + } + + /** * Parses the next record from the current point in the stream. * * @return the record as an array of values, or <tt>null</tt> if the end of the stream has been reached @@ -150,7 +162,7 @@ public class CSVParser implements Iterab * on parse error or input read-failure */ CSVRecord getRecord() throws IOException { - CSVRecord result = new CSVRecord(null, headerMap, null); + CSVRecord result = new CSVRecord(null, headerMap, null, recordNumber + 1); record.clear(); StringBuilder sb = null; do { @@ -185,8 +197,9 @@ public class CSVParser implements Iterab } while (reusableToken.type == TOKEN); if (!record.isEmpty()) { + recordNumber++; final String comment = sb == null ? null : sb.toString(); - result = new CSVRecord(record.toArray(new String[record.size()]), headerMap, comment); + result = new CSVRecord(record.toArray(new String[record.size()]), headerMap, comment, this.recordNumber); } return result; } Modified: commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVRecord.java URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVRecord.java?rev=1397895&r1=1397894&r2=1397895&view=diff ============================================================================== --- commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVRecord.java (original) +++ commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVRecord.java Sat Oct 13 17:09:48 2012 @@ -39,8 +39,12 @@ public class CSVRecord implements Serial /** The accumulated comments (if any) */ private final String comment; + + /** The record number. */ + private final long recordNumber; - CSVRecord(final String[] values, final Map<String, Integer> mapping, final String comment) { + CSVRecord(final String[] values, final Map<String, Integer> mapping, final String comment, long recordNumber) { + this.recordNumber = recordNumber; this.values = values != null ? values : EMPTY_STRING_ARRAY; this.mapping = mapping; this.comment = comment; @@ -107,6 +111,10 @@ public class CSVRecord implements Serial return comment; } + public long getRecordNumber() { + return recordNumber; + } + /** * Returns the number of values in this record. */ @@ -118,4 +126,5 @@ public class CSVRecord implements Serial public String toString() { return Arrays.toString(values); } + } Modified: commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java?rev=1397895&r1=1397894&r2=1397895&view=diff ============================================================================== --- commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java (original) +++ commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java Sat Oct 13 17:09:48 2012 @@ -18,6 +18,7 @@ package org.apache.commons.csv; import static org.apache.commons.csv.Constants.CRLF; +import static org.apache.commons.csv.Constants.CR; import static org.apache.commons.csv.Constants.LF; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -586,43 +587,88 @@ public class CSVParserTest { @Test public void testGetLineNumberWithLF() throws Exception { - final CSVParser parser = new CSVParser("a\nb\nc", CSVFormat.DEFAULT.withLineSeparator(LF)); - - assertEquals(0, parser.getLineNumber()); - assertNotNull(parser.getRecord()); - assertEquals(1, parser.getLineNumber()); - assertNotNull(parser.getRecord()); - assertEquals(2, parser.getLineNumber()); - assertNotNull(parser.getRecord()); - assertEquals(2, parser.getLineNumber()); - assertNull(parser.getRecord()); + validateLineNumbers(String.valueOf(LF)); } @Test public void testGetLineNumberWithCRLF() throws Exception { - final CSVParser parser = new CSVParser("a\r\nb\r\nc", CSVFormat.DEFAULT.withLineSeparator(CRLF)); + validateLineNumbers(CRLF); + } + + @Test + public void testGetLineNumberWithCR() throws Exception { + validateLineNumbers(String.valueOf(CR)); + } + + @Test + public void testGetRecordNumberWithLF() throws Exception { + validateRecordNumbers(String.valueOf(LF)); + } + @Test + public void testGetRecordWithMultiiLineValues() throws Exception { + final CSVParser parser = new CSVParser("\"a\r\n1\",\"a\r\n2\"" + CRLF + "\"b\r\n1\",\"b\r\n2\"" + CRLF + "\"c\r\n1\",\"c\r\n2\"", + CSVFormat.DEFAULT.withLineSeparator(CRLF)); + CSVRecord record; + assertEquals(0, parser.getRecordNumber()); assertEquals(0, parser.getLineNumber()); - assertNotNull(parser.getRecord()); - assertEquals(1, parser.getLineNumber()); - assertNotNull(parser.getRecord()); - assertEquals(2, parser.getLineNumber()); - assertNotNull(parser.getRecord()); - assertEquals(2, parser.getLineNumber()); - assertNull(parser.getRecord()); + assertNotNull(record = parser.getRecord()); + assertEquals(3, parser.getLineNumber()); + assertEquals(1, record.getRecordNumber()); + assertEquals(1, parser.getRecordNumber()); + assertNotNull(record = parser.getRecord()); + assertEquals(6, parser.getLineNumber()); + assertEquals(2, record.getRecordNumber()); + assertEquals(2, parser.getRecordNumber()); + assertNotNull(record = parser.getRecord()); + assertEquals(8, parser.getLineNumber()); + assertEquals(3, record.getRecordNumber()); + assertEquals(3, parser.getRecordNumber()); + assertNull(record = parser.getRecord()); + assertEquals(8, parser.getLineNumber()); + assertEquals(3, parser.getRecordNumber()); } @Test - public void testGetLineNumberWithCR() throws Exception { - final CSVParser parser = new CSVParser("a\rb\rc", CSVFormat.DEFAULT.withLineSeparator("\r")); + public void testGetRecordNumberWithCRLF() throws Exception { + validateRecordNumbers(CRLF); + } + @Test + public void testGetRecordNumberWithCR() throws Exception { + validateRecordNumbers(String.valueOf(CR)); + } + + private void validateRecordNumbers(String lineSeparator) throws IOException { + final CSVParser parser = new CSVParser("a" + lineSeparator + "b" + lineSeparator + "c", CSVFormat.DEFAULT.withLineSeparator(lineSeparator)); + CSVRecord record; + assertEquals(0, parser.getRecordNumber()); + assertNotNull(record = parser.getRecord()); + assertEquals(1, record.getRecordNumber()); + assertEquals(1, parser.getRecordNumber()); + assertNotNull(record = parser.getRecord()); + assertEquals(2, record.getRecordNumber()); + assertEquals(2, parser.getRecordNumber()); + assertNotNull(record = parser.getRecord()); + assertEquals(3, record.getRecordNumber()); + assertEquals(3, parser.getRecordNumber()); + assertNull(record = parser.getRecord()); + assertEquals(3, parser.getRecordNumber()); + } + + private void validateLineNumbers(String lineSeparator) throws IOException { + final CSVParser parser = new CSVParser("a" + lineSeparator + "b" + lineSeparator + "c", CSVFormat.DEFAULT.withLineSeparator(lineSeparator)); assertEquals(0, parser.getLineNumber()); assertNotNull(parser.getRecord()); assertEquals(1, parser.getLineNumber()); assertNotNull(parser.getRecord()); assertEquals(2, parser.getLineNumber()); assertNotNull(parser.getRecord()); + // Still 2 because the last line is does not have EOL chars assertEquals(2, parser.getLineNumber()); assertNull(parser.getRecord()); + // Still 2 because the last line is does not have EOL chars + assertEquals(2, parser.getLineNumber()); } + }