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
+        }
+    }
 }


Reply via email to