JAL-4243 Updated bio.tools record and JSON (version number)
[jalview.git] / utils / BufferedLineReader.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 import java.io.BufferedReader;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.StringReader;
25
26 /**
27  * A file reader that concatenates lines
28  * 
29  * @author gmcarstairs
30  *
31  */
32 public class BufferedLineReader
33 {
34   interface LineCleaner
35   {
36     String cleanLine(String l);
37   }
38
39   /*
40    * a reader for the file being read
41    */
42   private BufferedReader br;
43   
44   /*
45    * optional handler to post-process each line as it is read
46    */
47   private LineCleaner cleaner;
48
49   /*
50    * current buffer of <bufferSize> post-processed input lines
51    */
52   private String[] buffer;
53
54   private boolean atEof;
55
56   /**
57    * Constructor
58    * 
59    * @param reader
60    * @param bufferSize
61    *          the number of lines to concatenate at a time while reading
62    * @param tidier
63    *          an optional callback handler to post-process each line after
64    *          reading
65    * @throws FileNotFoundException
66    */
67   public BufferedLineReader(BufferedReader reader, int bufferSize,
68           LineCleaner tidier)
69           throws IOException
70   {
71     br = reader;
72     buffer = new String[bufferSize];
73     cleaner = tidier;
74
75     /*
76      * load up the buffer with N-1 lines, ready for the first read
77      */
78     for (int i = 1; i < bufferSize; i++)
79     {
80       readLine();
81     }
82
83   }
84
85   /**
86    * Reads the next line from file, invokes the post-processor if one was
87    * provided, and returns the 'cleaned' line, or null at end of file.
88    * 
89    * @return
90    */
91   private String readLine() // throws IOException
92   {
93     if (atEof)
94     {
95       return null;
96     }
97
98     String line = null;
99     try
100     {
101       line = br.readLine();
102     } catch (IOException e)
103     {
104       e.printStackTrace();
105     }
106     if (line == null)
107     {
108       atEof = true;
109       return null;
110     }
111     if (cleaner != null)
112     {
113       line = cleaner.cleanLine(line);
114     }
115
116     /*
117      * shuffle down the lines buffer and add the new line
118      * in the last position
119      */
120     for (int i = 1; i < buffer.length; i++)
121     {
122       buffer[i - 1] = buffer[i];
123     }
124     buffer[buffer.length - 1] = line;
125     return line;
126   }
127
128   /**
129    * Returns a number of concatenated lines from the file, or null at end of
130    * file.
131    * 
132    * @return
133    */
134   public String read()
135   {
136     if (readLine() == null)
137     {
138       return null;
139     }
140     StringBuilder result = new StringBuilder(100 * buffer.length);
141     for (String line : buffer)
142     {
143       if (line != null)
144       {
145         result.append(line);
146       }
147     }
148     return result.toString();
149   }
150
151   /**
152    * A main 'test' method!
153    * 
154    * @throws IOException
155    */
156   public static void main(String[] args) throws IOException
157   {
158     String data = "Now is the winter\n" + "Of our discontent\n"
159             + "Made glorious summer\n" + "By this sun of York\n";
160     BufferedReader br = new BufferedReader(new StringReader(data));
161     BufferedLineReader reader = new BufferedLineReader(br, 3,
162             new LineCleaner()
163             {
164               @Override
165               public String cleanLine(String l)
166               {
167                 return l.toUpperCase();
168               }
169             });
170     String line = reader.read();
171     String expect = "NOW IS THE WINTEROF OUR DISCONTENTMADE GLORIOUS SUMMER";
172     if (!line.equals(expect))
173     {
174       System.err.println("Fail: expected '" + expect + "', found '" + line
175               + ";");
176     }
177     else
178     {
179       System.out.println("Line one ok!");
180     }
181     line = reader.read();
182     expect = "OF OUR DISCONTENTMADE GLORIOUS SUMMERBY THIS SUN OF YORK";
183     if (!line.equals(expect))
184     {
185       System.err.println("Fail: expected '" + expect + "', found '" + line
186               + "'");
187     }
188     else
189     {
190       System.out.println("Line two ok!!");
191     }
192     line = reader.read();
193     if (line != null)
194     {
195       System.err.println("Fail: expected null at eof, got '" + line + "'");
196     }
197     else
198     {
199       System.out.println("EOF ok!!!");
200     }
201   }
202 }