View Javadoc

1   /*
2   	StatCvs - CVS statistics generation 
3   	Copyright (C) 2002  Lukasz Pekacki <lukasz@pekacki.de>
4   	http://statcvs.sf.net/
5       
6   	This library is free software; you can redistribute it and/or
7   	modify it under the terms of the GNU Lesser General Public
8   	License as published by the Free Software Foundation; either
9   	version 2.1 of the License, or (at your option) any later version.
10  
11  	This library is distributed in the hope that it will be useful,
12  	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  	Lesser General Public License for more details.
15  
16  	You should have received a copy of the GNU Lesser General Public
17  	License along with this library; if not, write to the Free Software
18  	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19      
20  	$RCSfile: LookaheadReader.java,v $
21  	$Date: 2008/04/02 11:22:15 $
22  */
23  package net.sf.statcvs.util;
24  
25  import java.io.BufferedReader;
26  import java.io.IOException;
27  import java.io.Reader;
28  import java.util.NoSuchElementException;
29  
30  /**
31   * <p>Wraps a {@link java.io.Reader} for line-by-line access.
32   * This works like {@link java.util.Iterator}: {@link #hasNextLine}
33   * returns true if another line can be read; {@link #nextLine} reads
34   * the next line and returns it. Additionally, {@link #getCurrentLine}
35   * can be used to access multiple times the line returned by
36   * <tt>nextLine()</tt>.</p>
37   * 
38   * <p>At construction time, <tt>getCurrentLine()</tt> is undefined.
39   * <tt>nextLine()</tt> must be called once to read the first line.</p>
40   * 
41   * @author Richard Cyganiak (richard@cyganiak.de)
42   * @version $Id: LookaheadReader.java,v 1.4 2008/04/02 11:22:15 benoitx Exp $
43   */
44  public class LookaheadReader {
45      private final BufferedReader reader;
46      private String currentLine = null;
47      private String nextLine = null;
48      private boolean afterEnd = false;
49      private int lineNumber = 0;
50  
51      /**
52       * Creates a LookaheadReader from a source reader.
53       * @param reader a reader whose contents will be returned by the
54       * 			LookaheadReader
55       */
56      public LookaheadReader(final Reader reader) {
57          this.reader = new BufferedReader(reader);
58      }
59  
60      /**
61       * Returns the current line without reading a line from the source
62       * reader. Will throw an exception if {@link #nextLine} was not
63       * called before.
64       * @return The line returned by the previous call to {@link #nextLine()}
65       * @throws NoSuchElementException if {@link #nextLine} was not yet called
66       */
67      public String getCurrentLine() {
68          if (this.currentLine == null) {
69              throw new NoSuchElementException("Call to getCurrentLine() before nextLine() was called");
70          }
71          return this.currentLine;
72      }
73  
74      /**
75       * Reads and returns a line from the source reader. The result of
76       * this call will be the new current line. Will throw an exception
77       * if trying to read from after the end of the source reader.
78       * @return The next line of the source reader
79       * @throws IOException on error while reading the source reader
80       * @throws NoSuchElementException if {@link #hasNextLine} is false 
81       */
82      public String nextLine() throws IOException {
83          if (!hasNextLine()) {
84              throw new NoSuchElementException("Call to nextLine() when hasNextLine() is false");
85          }
86          this.currentLine = this.nextLine;
87          this.nextLine = null;
88          this.lineNumber++;
89          return this.currentLine;
90      }
91  
92      /**
93       * Checks if more lines are available for reading.
94       * @return <tt>true</tt> if at least one more line can be read
95       * @throws IOException on error while reading the source reader
96       */
97      public boolean hasNextLine() throws IOException {
98          if (this.afterEnd) {
99              return false;
100         }
101         if (this.nextLine != null) {
102             return true;
103         }
104         this.nextLine = this.reader.readLine();
105         if (this.nextLine != null) {
106             return true;
107         }
108         this.afterEnd = true;
109         return false;
110     }
111 
112     /**
113      * Returns the number of the line that would be returned by
114      * {@link #getCurrentLine}, or 0 before the first
115      * call to {@link #nextLine}. The first line has line number 1.
116      * @return the current line number
117      */
118     public int getLineNumber() {
119         return this.lineNumber;
120     }
121 }