Author: scolebourne Date: Tue Mar 7 14:26:37 2006 New Revision: 384037 URL: http://svn.apache.org/viewcvs?rev=384037&view=rev Log: Further adjustments to javadoc/implementation of LineIterator
Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?rev=384037&r1=384036&r2=384037&view=diff ============================================================================== --- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java (original) +++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java Tue Mar 7 14:26:37 2006 @@ -24,8 +24,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.io.FileReader; -import java.io.Reader; import java.net.URL; import java.util.Collection; import java.util.Date; @@ -70,6 +68,7 @@ * @author Chris Eldredge * @author Jim Harrington * @author Niall Pemberton + * @author Sandy McArthur * @version $Id$ */ public class FileUtils { @@ -925,9 +924,28 @@ /** * Return an Iterator for the lines in a <code>File</code>. - * This neccessitates creating an InputStream for the file. The only ways - * to close this stream are to call [EMAIL PROTECTED] LineIterator#close()} or let - * the <code>LineIterator</code> be garbage collected. + * <p> + * This method opens an <code>InputStream</code> for the file. + * When you have finished with the iterator you should close the stream + * to free internal resources. This can be done by calling the + * [EMAIL PROTECTED] LineIterator#close()} or + * [EMAIL PROTECTED] LineIterator#closeQuietly(LineIterator)} method. + * <p> + * The recommended usage pattern is: + * <pre> + * LineIterator it = FileUtils.lineIterator(file, "UTF-8"); + * try { + * while (it.hasNext()) { + * String line = it.nextLine(); + * /// do something with line + * } + * } finally { + * LineIterator.closeQuietly(iterator); + * } + * </pre> + * <p> + * If an exception occurs during the creation of the iterator, the + * underlying stream is closed. * <p> * There is no lineIterator method without encoding parameter because * the default encoding can differ between platforms and will have Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java?rev=384037&r1=384036&r2=384037&view=diff ============================================================================== --- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java (original) +++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java Tue Mar 7 14:26:37 2006 @@ -74,6 +74,7 @@ * @author Gareth Davis * @author Ian Springer * @author Niall Pemberton + * @author Sandy McArthur * @version $Id$ */ public class IOUtils { @@ -509,13 +510,30 @@ //----------------------------------------------------------------------- /** * Return an Iterator for the lines in a <code>Reader</code>. - * Unless you keep a reference to the <code>InputStream</code> the - * only way to close it is to call [EMAIL PROTECTED] LineIterator#close()} or - * wait for the garbage collector. + * <p> + * <code>LineIterator</code> holds a reference to the open + * <code>Reader</code> specified here. When you have finished with the + * iterator you should close the reader to free internal resources. + * This can be done by closing the reader directly, or by calling the + * [EMAIL PROTECTED] #close()} or [EMAIL PROTECTED] #closeQuietly(LineIterator)} method on + * the iterator. + * <p> + * The recommended usage pattern is: + * <pre> + * try { + * LineIterator it = IOUtils.lineIterator(reader); + * while (it.hasNext()) { + * String line = it.nextLine(); + * /// do something with line + * } + * } finally { + * IOUtils.closeQuietly(reader); + * } + * </pre> * * @param reader the <code>Reader</code> to read from, not null * @return an Iterator of the lines in the reader, never null - * @throws NullPointerException if the reader is null + * @throws IllegalArgumentException if the reader is null * @since Commons IO 1.2 */ public static LineIterator lineIterator(Reader reader) { @@ -525,14 +543,31 @@ /** * Return an Iterator for the lines in an <code>InputStream</code>, using * the character encoding specified (or default encoding if null). - * Unless you keep a reference to the <code>InputStream</code> the - * only way to close it is to call [EMAIL PROTECTED] LineIterator#close()} or - * wait for the garbage collector. + * <p> + * <code>LineIterator</code> holds a reference to the open + * <code>InputStream</code> specified here. When you have finished with + * the iterator you should close the reader to free internal resources. + * This can be done by closing the reader directly, or by calling the + * [EMAIL PROTECTED] #close()} or [EMAIL PROTECTED] #closeQuietly(LineIterator)} method on + * the iterator. + * <p> + * The recommended usage pattern is: + * <pre> + * try { + * LineIterator it = IOUtils.lineIterator(stream, "UTF-8"); + * while (it.hasNext()) { + * String line = it.nextLine(); + * /// do something with line + * } + * } finally { + * IOUtils.closeQuietly(stream); + * } + * </pre> * * @param input the <code>InputStream</code> to read from, not null * @param encoding the encoding to use, null means platform default * @return an Iterator of the lines in the reader, never null - * @throws NullPointerException if the input is null + * @throws IllegalArgumentException if the input is null * @throws IOException if an I/O error occurs, such as if the encoding is invalid * @since Commons IO 1.2 */ Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java?rev=384037&r1=384036&r2=384037&view=diff ============================================================================== --- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java (original) +++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java Tue Mar 7 14:26:37 2006 @@ -22,11 +22,25 @@ /** * An Iterator over the lines in a <code>Reader</code>. - * * <p> - * If you do not wish to maintain a reference to the <code>Reader</code> - * you can call [EMAIL PROTECTED] #close()} to close the backing <code>Reader</code> - * and free an interal resources. + * <code>LineIterator</code> holds a reference to an open <code>Reader</code>. + * When you have finished with the iterator you should close the reader + * to free internal resources. This can be done by closing the reader directly, + * or by calling the [EMAIL PROTECTED] #close()} or [EMAIL PROTECTED] #closeQuietly(LineIterator)} + * method on the iterator. + * <p> + * The recommended usage pattern is: + * <pre> + * LineIterator it = FileUtils.lineIterator(file, "UTF-8"); + * try { + * while (it.hasNext()) { + * String line = it.nextLine(); + * /// do something with line + * } + * } finally { + * LineIterator.closeQuietly(iterator); + * } + * </pre> * * @author Niall Pemberton * @author Stephen Colebourne @@ -34,11 +48,7 @@ * @version $Id$ * @since Commons IO 1.2 */ -/* - * XXX: hasNext() should be reworked so this class can be - * meaningfully subclassed before the final below is removed. - */ -public final class LineIterator { +public class LineIterator { /** The reader that is being read. */ private final BufferedReader bufferedReader; @@ -55,7 +65,7 @@ */ public LineIterator(final Reader reader) throws IllegalArgumentException { if (reader == null) { - throw new IllegalArgumentException("Reader must not be null."); + throw new IllegalArgumentException("Reader must not be null"); } if (reader instanceof BufferedReader) { bufferedReader = (BufferedReader) reader; @@ -80,18 +90,31 @@ return false; } else { try { - cachedLine = bufferedReader.readLine(); - if (cachedLine == null) { - finished = true; - return false; - } else { - return true; + while (true) { + String line = bufferedReader.readLine(); + if (line == null) { + finished = true; + return false; + } else if (isValidLine(line)) { + cachedLine = line; + return true; + } } } catch(IOException ioe) { close(); throw new IllegalStateException(ioe.toString()); } } + } + + /** + * Overridable method to validate each line that is returned. + * + * @param line the line that is to be validated + * @return true if valid, false to remove from the iterator + */ + protected boolean isValidLine(String line) { + return true; } /** Modified: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java?rev=384037&r1=384036&r2=384037&view=diff ============================================================================== --- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java (original) +++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java Tue Mar 7 14:26:37 2006 @@ -17,6 +17,7 @@ import java.io.File; import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.io.UnsupportedEncodingException; @@ -116,10 +117,11 @@ LineIterator iterator = null; try { iterator = FileUtils.lineIterator(testFile, "UTF-8"); - iterator.close(); fail("Expected FileNotFoundException"); } catch(FileNotFoundException expected) { // ignore, expected result + } finally { + LineIterator.closeQuietly(iterator); } } @@ -133,13 +135,16 @@ createFile(testFile, encoding, 3); LineIterator iterator = FileUtils.lineIterator(testFile, encoding); - int count = 0; - while (iterator.hasNext()) { - assertTrue(iterator.next() instanceof String); - count++; + try { + int count = 0; + while (iterator.hasNext()) { + assertTrue(iterator.next() instanceof String); + count++; + } + assertEquals(3, count); + } finally { + LineIterator.closeQuietly(iterator); } - iterator.close(); - assertEquals(3, count); } /** @@ -154,10 +159,11 @@ LineIterator iterator = null; try { iterator = FileUtils.lineIterator(testFile, encoding); - iterator.close(); fail("Expected UnsupportedEncodingException"); } catch(UnsupportedEncodingException expected) { // ignore, expected result + } finally { + LineIterator.closeQuietly(iterator); } } @@ -171,12 +177,15 @@ List lines = createFile(testFile, encoding, 3); LineIterator iterator = FileUtils.lineIterator(testFile, encoding); - for (int i = 0; i < lines.size(); i++) { - String line = (String)iterator.next(); - assertEquals("next() line " + i, lines.get(i), line); + try { + for (int i = 0; i < lines.size(); i++) { + String line = (String)iterator.next(); + assertEquals("next() line " + i, lines.get(i), line); + } + assertEquals("No more expected", false, iterator.hasNext()); + } finally { + LineIterator.closeQuietly(iterator); } - assertEquals("No more expected", false, iterator.hasNext()); - iterator.close(); } /** @@ -189,12 +198,15 @@ List lines = createFile(testFile, encoding, 3); LineIterator iterator = FileUtils.lineIterator(testFile, encoding); - for (int i = 0; i < lines.size(); i++) { - String line = iterator.nextLine(); - assertEquals("nextLine() line " + i, lines.get(i), line); + try { + for (int i = 0; i < lines.size(); i++) { + String line = iterator.nextLine(); + assertEquals("nextLine() line " + i, lines.get(i), line); + } + assertFalse("No more expected", iterator.hasNext()); + } finally { + LineIterator.closeQuietly(iterator); } - assertFalse("No more expected", iterator.hasNext()); - iterator.close(); } /** @@ -208,43 +220,44 @@ createFile(testFile, encoding, 3); LineIterator iterator = FileUtils.lineIterator(testFile, encoding); - - // get - assertTrue("Line expected", iterator.next() instanceof String); - assertTrue("More expected", iterator.hasNext()); - - // close - iterator.close(); - assertFalse("No more expected", iterator.hasNext()); try { - iterator.next(); - fail(); - } catch (NoSuchElementException ex) { - // expected - } - try { - iterator.nextLine(); - fail(); - } catch (NoSuchElementException ex) { - // expected - } - - // try closing again - iterator.close(); - try { - iterator.next(); - fail(); - } catch (NoSuchElementException ex) { - // expected - } - try { - iterator.nextLine(); - fail(); - } catch (NoSuchElementException ex) { - // expected + // get + assertTrue("Line expected", iterator.next() instanceof String); + assertTrue("More expected", iterator.hasNext()); + + // close + iterator.close(); + assertFalse("No more expected", iterator.hasNext()); + try { + iterator.next(); + fail(); + } catch (NoSuchElementException ex) { + // expected + } + try { + iterator.nextLine(); + fail(); + } catch (NoSuchElementException ex) { + // expected + } + + // try closing again + iterator.close(); + try { + iterator.next(); + fail(); + } catch (NoSuchElementException ex) { + // expected + } + try { + iterator.nextLine(); + fail(); + } catch (NoSuchElementException ex) { + // expected + } + } finally { + LineIterator.closeQuietly(iterator); } - - iterator.close(); } /** @@ -259,38 +272,39 @@ List lines = createFile(testFile, encoding, lineCount); LineIterator iterator = FileUtils.lineIterator(testFile, encoding); - - try { - iterator.remove(); - fail("Remove is unsupported"); - } catch (UnsupportedOperationException ex) { - // expected - } - - int idx = 0; - while (iterator.hasNext()) { - String line = (String)iterator.next(); - assertEquals("Comparing line " + idx, lines.get(idx), line); - assertTrue("Exceeded expected idx=" + idx + " size=" + lines.size(), idx < lines.size()); - idx++; - } - assertEquals("Line Count doesn't match", idx, lines.size()); - - // try calling next() after file processed - try { - iterator.next(); - fail("Expected NoSuchElementException"); - } catch (NoSuchElementException expected) { - // ignore, expected result - } try { - iterator.nextLine(); - fail("Expected NoSuchElementException"); - } catch (NoSuchElementException expected) { - // ignore, expected result + try { + iterator.remove(); + fail("Remove is unsupported"); + } catch (UnsupportedOperationException ex) { + // expected + } + + int idx = 0; + while (iterator.hasNext()) { + String line = (String)iterator.next(); + assertEquals("Comparing line " + idx, lines.get(idx), line); + assertTrue("Exceeded expected idx=" + idx + " size=" + lines.size(), idx < lines.size()); + idx++; + } + assertEquals("Line Count doesn't match", idx, lines.size()); + + // try calling next() after file processed + try { + iterator.next(); + fail("Expected NoSuchElementException"); + } catch (NoSuchElementException expected) { + // ignore, expected result + } + try { + iterator.nextLine(); + fail("Expected NoSuchElementException"); + } catch (NoSuchElementException expected) { + // ignore, expected result + } + } finally { + LineIterator.closeQuietly(iterator); } - - iterator.close(); } /** @@ -304,6 +318,63 @@ } FileUtils.writeLines(file, encoding, lines); return lines; + } + + //----------------------------------------------------------------------- + public void testFiltering() throws Exception { + String encoding = "UTF-8"; + + String fileName = "LineIterator-Filter-test.txt"; + File testFile = new File(getTestDirectory(), fileName); + List lines = createFile(testFile, encoding, 9); + + Reader reader = new FileReader(testFile); + LineIterator iterator = new LineIterator(reader) { + protected boolean isValidLine(String line) { + char c = line.charAt(line.length() - 1); + return ((c - 48) % 3 != 1); + } + }; + try { + try { + iterator.remove(); + fail("Remove is unsupported"); + } catch (UnsupportedOperationException ex) { + // expected + } + + int idx = 0; + int actualLines = 0; + while (iterator.hasNext()) { + String line = (String) iterator.next(); + actualLines++; + assertEquals("Comparing line " + idx, lines.get(idx), line); + assertTrue("Exceeded expected idx=" + idx + " size=" + lines.size(), idx < lines.size()); + idx++; + if (idx % 3 == 1) { + idx++; + } + } + assertEquals("Line Count doesn't match", 9, lines.size()); + assertEquals("Line Count doesn't match", 9, idx); + assertEquals("Line Count doesn't match", 6, actualLines); + + // try calling next() after file processed + try { + iterator.next(); + fail("Expected NoSuchElementException"); + } catch (NoSuchElementException expected) { + // ignore, expected result + } + try { + iterator.nextLine(); + fail("Expected NoSuchElementException"); + } catch (NoSuchElementException expected) { + // ignore, expected result + } + } finally { + LineIterator.closeQuietly(iterator); + } } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]