001: /*
002: * Copyright (C) 2001, 2002 Robert MacGrogan
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: *
019: * $Archive: SourceJammer$
020: * $FileName: TextLineReader2.java$
021: * $FileID: 4310$
022: *
023: * Last change:
024: * $AuthorName: Rob MacGrogan$
025: * $Date: 4/23/03 5:24 PM$
026: * $VerID: 8791$
027: * $Comment: Replaced GPL header with LGPL header.$
028: *
029: */
030: package org.sourcejammer.util;
031:
032: import java.util.Collection;
033: import java.util.Iterator;
034: import java.util.Vector;
035: import java.util.Enumeration;
036: import java.io.ByteArrayInputStream;
037: import java.io.InputStreamReader;
038: import java.io.BufferedReader;
039: import java.io.IOException;
040: import java.io.InputStream;
041:
042: /**
043: * @author $AuthorName: Rob MacGrogan$
044: * @version $VerNum: 2$
045: * $KeyWordsOff: $<br><br>
046: *
047: *
048: * Mostly copied from org.sourcejammer.server.source.TextLineReader. This bad form,
049: * but it was easier to do that refactoring that class to extend this one, which
050: * is what i will do eventually.
051: */
052: public class TextLineReader2 {
053:
054: private Vector mvecLines;
055: private int miIndex;
056: private int miSize;
057: private InputStream inStr = null;
058: private boolean expandKeywords = false;
059:
060: /**
061: * Constructs a TextLineReader from the passed-in byte array.
062: *
063: * @param buf -- a byte array that is a binary representation of a text file.
064: */
065: public TextLineReader2(byte[] buf) throws IOException {
066: this (buf, 0, buf.length);
067: }
068:
069: /**
070: * Constructs a new NextLineReader explicitly setting the underlying Vector
071: * to a Vector of Strings. Used for storing the contents of a TextLineReader
072: * object without explicitly serializing this object. Vector is serialized instead.
073: */
074: public TextLineReader2(Collection col) {
075:
076: //We neeAetermine the size and make sure that all elements in the
077: //Vector are String. So we loop through the Vector.
078: Iterator itr = col.iterator();
079: int iCharCount = 0;
080: while (itr.hasNext()) {
081: try {
082: String s = (String) itr.next();
083: iCharCount += s.length();
084: } catch (ClassCastException ex) {
085: throw new ConfigurationException(
086: "The Collection used to construct TextLineReader contains a non-String element.",
087: ex);
088: }
089: }
090: miSize = iCharCount;
091: mvecLines = new Vector(col);
092: miIndex = -1;
093: }
094:
095: /**
096: * Constructs a TextLineReader from the specified bytes in the passed-in
097: * byte array.
098: *
099: * @param buf -- a byte array that is a binary representation of a text file.
100: * @param offset -- byte in the buf at which read should begin.
101: * @param length -- number of bytes in buf to read.
102: */
103: public TextLineReader2(byte[] buf, int offset, int length)
104: throws IOException {
105: ByteArrayInputStream oByStream = new ByteArrayInputStream(buf,
106: offset, length);
107: inStr = oByStream;
108: //Stream left open. Remember to close on finalize of class.
109: }
110:
111: /**
112: * Constructs a TextLineReader to read the bytes from the passed in InputStream.
113: *
114: * @param st -- an InputStream for streaming in bytes which are a binary
115: * representation of a text file.
116: */
117: public TextLineReader2(InputStream st) throws IOException {
118: inStr = st;
119: //init();
120: }
121:
122: /**
123: * Initializes the TextLineReader. Reads all of the bytes from the InputStream
124: * and converts them to lines of text stored in a Vector. No need call if this class
125: * was constructed with Vector constructor.
126: */
127: public void init() throws IOException {
128: mvecLines = new Vector();
129: miSize = 0;
130: InputStreamReader oInStreamRead = new InputStreamReader(inStr);
131:
132: try {
133: BufferedReader oBuffRead = new BufferedReader(oInStreamRead);
134: try {
135: BufferedLineReader reader = new BufferedLineReader(
136: oBuffRead);
137: boolean bContinueReadingLines = true;
138: while (bContinueReadingLines) {
139: String sLine = reader.readLine();
140: if (sLine != null) {
141: miSize += sLine.length();
142: mvecLines.add(sLine);
143: }//end if line not null
144: else {
145: bContinueReadingLines = false;
146: }
147: }
148: miIndex = -1;
149: } finally {
150: oBuffRead.close();
151: }
152: } finally {
153: try {
154: oInStreamRead.close();
155: } finally {
156: inStr.close();
157: }
158: }
159: }
160:
161: /**
162: * Returns the number of lines in the TextLineReader.
163: */
164: public int getNumLines() {
165: return mvecLines.size();
166: }
167:
168: /**
169: * Sets the index to the specified line number.
170: *
171: * @param index -- the line number to set the index to.
172: *
173: * @exception EndOfSourceException -- if the TextLineReader does not
174: * contain a line with the specified index.
175: */
176: public void setIndex(int index) throws TextLineReaderException {
177: if (index < mvecLines.size()) {
178: miIndex = index;
179: } else {
180: throw new TextLineReaderException(
181: "The index is outside the scope of this TextLineInputStream");
182: }
183: }
184:
185: /**
186: * Returns the line with the specified index.
187: *
188: * @param index -- a line number.
189: * @return the line at the requested index.
190: */
191: public String getLine(int index) {
192: return (String) mvecLines.get(index);
193: }
194:
195: /**
196: * Returns true if the TextLineReader contains additional lines after the
197: * current index.
198: */
199: public boolean hasMoreLines() {
200: boolean bReturn = false;
201: if (miIndex < mvecLines.size() - 1) {
202: bReturn = true;
203: }
204: return bReturn;
205: }
206:
207: /**
208: * Moves the index ahead by the specified number of lines.
209: *
210: * @param numLines -- number of lines to skip.
211: * @exxception EndOfSourceException -- if skipping the specified number of
212: * lines would take the index past the last line in the TextLineReader.
213: */
214: public void skipLines(int numLines) throws TextLineReaderException {
215: if (miIndex + numLines < mvecLines.size()) {
216: miIndex += numLines;
217: } else {
218: throw new TextLineReaderException(
219: "Cannot skip requested number of lines. End of source encountered.");
220: }
221: }
222:
223: /**
224: * Returns the next line and advances the index.
225: *
226: * @return the next line, as String.
227: * @exception EndOfSourceException if there is no next line.
228: */
229: public String getNextLine() throws TextLineReaderException {
230: String sReturn = null;
231: if (miIndex + 1 < mvecLines.size()) {
232: miIndex++;
233: sReturn = (String) mvecLines.get(miIndex);
234: } else {
235: throw new TextLineReaderException(
236: "No lines remaining in TextLineIterator.");
237: }
238: return sReturn;
239: }
240:
241: /**
242: * Returns the total number of characters in all the lines in this
243: * TextLineReader.
244: */
245: public int size() {
246: return miSize;
247: }
248:
249: public int getIndex() {
250: return miIndex;
251: }
252:
253: /**
254: * Advances the iterator to the next line. Returns true if this was
255: * successful. Returns false when end of file is reached.
256: */
257: public boolean next() {
258: boolean bNextSuccessful = true;
259: try {
260: setIndex(miIndex + 1);
261: } catch (TextLineReaderException ex) {
262: bNextSuccessful = false;
263: }
264: return bNextSuccessful;
265: }
266:
267: /**
268: * Returns the current line without adavancing the iterator.
269: */
270: public String getCurrentLine() throws TextLineReaderException {
271: if (miIndex < 0) {
272: throw new TextLineReaderException(
273: "There is no current line. Index is at beginnig of file.");
274: }
275: return (String) mvecLines.get(miIndex);
276: }
277:
278: /**
279: * Returns true if the the object is a TextLineReader and the current
280: * line of the object is equal to the current line of this TextLineReader.
281: */
282: public boolean equals(Object o) {
283: boolean bEqual = false;
284: try {
285: TextLineReader2 oComp = (TextLineReader2) o;
286: if (((String) mvecLines.get(miIndex))
287: .equals(((String) oComp.mvecLines
288: .get(oComp.miIndex)))) {
289: bEqual = true;
290: }
291: } catch (ClassCastException ex) {
292: bEqual = false;
293: }
294: return bEqual;
295: }
296:
297: /**
298: * Returns contents of this TextLineReader (the entire text file) as a
299: * StringBuffer, using the passed in eol as the end of line String.
300: */
301: public StringBuffer toStringBuffer(String eol) {
302: if (eol == null || eol.equals("")) {
303: throw new BadMethodArgumentException(
304: "Invalid end of line string.");
305: }
306: StringBuffer strReturn = new StringBuffer();
307: Enumeration enm = mvecLines.elements();
308: int iNumLines = mvecLines.size();
309: int iLineCounter = 0;
310: while (enm.hasMoreElements()) {
311: iLineCounter++;
312: String sLine = (String) enm.nextElement();
313: strReturn.append(sLine);
314: //We don't need to add an EOL on last line.
315: if (iLineCounter < iNumLines) {
316: strReturn.append(eol);
317: }
318: }
319: return strReturn;
320: }
321:
322: /**
323: * Returns contents of this TextLineReader (the entire text file) as a
324: * String, using the passed in eol as the end of line String.
325: */
326: public String toString(String eol) {
327: return toStringBuffer(eol).toString();
328: }
329:
330: /**
331: * Returns contents of this TextLineReader (the entire text file) as a
332: * String, the default end of line chars (from AppConfig) as the end of line
333: * String.
334: */
335: public String toString() {
336: char[] caEol = AppConfig.getInstance().getDefaultEndOfLine();
337: String sEol = new String(caEol);
338: return toString(sEol);
339: }
340:
341: public char[] toCharArray(String eol) {
342: return toString(eol).toCharArray();
343: }
344:
345: public char[] toCharArray() {
346: return toString().toCharArray();
347: }
348:
349: public Vector getUnderlyingVector() {
350: return (Vector) mvecLines.clone();
351: }
352:
353: public Vector toVector() {
354: return (Vector) mvecLines.clone();
355: }
356:
357: }
|