Author: ebourg Date: Wed Nov 9 23:04:13 2011 New Revision: 1200024 URL: http://svn.apache.org/viewvc?rev=1200024&view=rev Log: Made CSVParser iterable to simplify the iteration over the records
Modified: commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java commons/sandbox/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java Modified: commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java URL: http://svn.apache.org/viewvc/commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java?rev=1200024&r1=1200023&r2=1200024&view=diff ============================================================================== --- commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java (original) +++ commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVParser.java Wed Nov 9 23:04:13 2011 @@ -20,7 +20,9 @@ package org.apache.commons.csv; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import static org.apache.commons.csv.CSVParser.Token.Type.*; @@ -33,14 +35,18 @@ import static org.apache.commons.csv.CSV * <p>Parsing of a csv-string having tabs as separators, * '"' as an optional value encapsulator, and comments starting with '#':</p> * <pre> - * String[][] record = - * (new CSVParser(new StringReader("a\tb\nc\td"), new CSVFormat('\t','"','#'))).getAllValues(); + * CSVFormat format = new CSVFormat('\t', '"', '#'); + * Reader in = new StringReader("a\tb\nc\td"); + * String[][] records = new CSVParser(in, format).getRecords(); * </pre> * - * <p>Parsing of a csv-string in Excel CSV format</p> + * <p>Parsing of a csv-string in Excel CSV format, using a for-each loop:</p> * <pre> - * String[][] record = - * (new CSVParser(new StringReader("a;b\nc;d"), CSVFormat.EXCEL)).getAllValues(); + * Reader in = new StringReader("a;b\nc;d"); + * CSVParser parser = new CSVParser(in, CSVFormat.EXCEL); + * for (String[] record : parser) { + * ... + * } * </pre> * * <p> @@ -50,7 +56,7 @@ import static org.apache.commons.csv.CSV * <p>see <a href="package-summary.html">package documentation</a> * for more details</p> */ -public class CSVParser { +public class CSVParser implements Iterable<String[]> { /** length of the initial token (content-)buffer */ private static final int INITIAL_TOKEN_LENGTH = 50; @@ -172,7 +178,7 @@ public class CSVParser { * ('null' when end of file has been reached) * @throws IOException on parse error or input read-failure */ - public String[] getLine() throws IOException { + String[] getLine() throws IOException { String[] ret = EMPTY_STRING_ARRAY; record.clear(); while (true) { @@ -209,6 +215,49 @@ public class CSVParser { } /** + * Returns an iterator on the records. IOExceptions occuring + * during the iteration are wrapped in a RuntimeException. + */ + public Iterator<String[]> iterator() { + return new Iterator<String[]>() { + String[] current; + + public boolean hasNext() { + if (current == null) { + current = getNextLine(); + } + + return current != null; + } + + public String[] next() { + String[] next = current; + current = null; + + if (next == null) { + // hasNext() wasn't called before + next = getNextLine(); + if (next == null) { + throw new NoSuchElementException("No more CSV records available"); + } + } + + return next; + } + + private String[] getNextLine() { + try { + return getLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void remove() { } + }; + } + + /** * Returns the current line number in the input stream. * <p/> * ATTENTION: in case your csv has multiline-values the returned Modified: commons/sandbox/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java?rev=1200024&r1=1200023&r2=1200024&view=diff ============================================================================== --- commons/sandbox/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java (original) +++ commons/sandbox/csv/trunk/src/test/java/org/apache/commons/csv/CSVParserTest.java Wed Nov 9 23:04:13 2011 @@ -20,7 +20,11 @@ package org.apache.commons.csv; import java.io.IOException; import java.io.Reader; import java.io.StringReader; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; import junit.framework.TestCase; @@ -219,7 +223,7 @@ public class CSVParserTest extends TestC assertTrue(parser.getLine() == null); } - public void testGetAllValues() throws IOException { + public void testGetRecords() throws IOException { CSVParser parser = new CSVParser(new StringReader(code)); String[][] tmp = parser.getRecords(); assertEquals(res.length, tmp.length); @@ -518,7 +522,7 @@ public class CSVParserTest extends TestC public void testUnicodeEscape() throws IOException { String code = "abc,\\u0070\\u0075\\u0062\\u006C\\u0069\\u0063"; CSVParser parser = new CSVParser(new StringReader(code), CSVFormat.DEFAULT.withUnicodeEscapesInterpreted(true)); - String[] data = parser.getLine(); + String[] data = parser.iterator().next(); assertEquals(2, data.length); assertEquals("abc", data[0]); assertEquals("public", data[1]); @@ -565,4 +569,42 @@ public class CSVParserTest extends TestC assertEquals(TOKEN + ";five;", parser.testNextToken()); assertEquals(EOF + ";six;", parser.testNextToken()); } + + public void testForEach() { + List<String[]> records = new ArrayList<String[]>(); + + String code = "a,b,c\n1,2,3\nx,y,z"; + Reader in = new StringReader(code); + + for (String[] record : new CSVParser(in)) { + records.add(record); + } + + assertEquals(3, records.size()); + assertTrue(Arrays.equals(new String[] {"a", "b", "c"}, records.get(0))); + assertTrue(Arrays.equals(new String[]{"1", "2", "3"}, records.get(1))); + assertTrue(Arrays.equals(new String[] {"x", "y", "z"}, records.get(2))); + } + + public void testIterator() { + String code = "a,b,c\n1,2,3\nx,y,z"; + Iterator<String[]> iterator = new CSVParser(new StringReader(code)).iterator(); + + assertTrue(iterator.hasNext()); + iterator.remove(); + assertTrue(Arrays.equals(new String[]{"a", "b", "c"}, iterator.next())); + assertTrue(Arrays.equals(new String[]{"1", "2", "3"}, iterator.next())); + assertTrue(iterator.hasNext()); + assertTrue(iterator.hasNext()); + assertTrue(iterator.hasNext()); + assertTrue(Arrays.equals(new String[]{"x", "y", "z"}, iterator.next())); + assertFalse(iterator.hasNext()); + + try { + iterator.next(); + fail("NoSuchElementException expected"); + } catch (NoSuchElementException e) { + // expected + } + } }