001: /* ========================================================================
002: * JCommon : a free general purpose class library for the Java(tm) platform
003: * ========================================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jcommon/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * ----------------------
028: * LineBreakIterator.java
029: * ----------------------
030: * (C)opyright 2003, by Thomas Morgner and Contributors.
031: *
032: * Original Author: Thomas Morgner;
033: * Contributor(s): David Gilbert (for Object Refinery Limited);
034: *
035: * $Id: LineBreakIterator.java,v 1.4 2005/11/03 09:55:26 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 13-03-2003 : Initial version
040: */
041: package org.jfree.util;
042:
043: import java.util.Iterator;
044:
045: /**
046: * An iterator that breaks text into lines.
047: * The result is equal to BufferedReader.readLine().
048: *
049: * @author Thomas Morgner
050: */
051: public class LineBreakIterator implements Iterator {
052: /** A useful constant. */
053: public static final int DONE = -1;
054:
055: /** Storage for the text. */
056: private char[] text;
057:
058: /** The current position. */
059: private int position;
060:
061: /**
062: * Default constructor.
063: */
064: public LineBreakIterator() {
065: setText("");
066: }
067:
068: /**
069: * Creates a new line break iterator.
070: *
071: * @param text the text to be broken up.
072: */
073: public LineBreakIterator(final String text) {
074: setText(text);
075: }
076:
077: /**
078: * Returns the position of the next break.
079: *
080: * @return A position.
081: */
082: public synchronized int nextPosition() {
083: if (this .text == null) {
084: return DONE;
085: }
086: if (this .position == DONE) {
087: return DONE;
088: }
089:
090: // recognize \n, \r, \r\n
091:
092: final int nChars = this .text.length;
093: int nextChar = this .position;
094:
095: for (;;) {
096: if (nextChar >= nChars) {
097: /* End of text reached */
098: this .position = DONE;
099: return DONE;
100: }
101:
102: boolean eol = false;
103: char c = 0;
104: int i;
105:
106: // search the next line break, either \n or \r
107: for (i = nextChar; i < nChars; i++) {
108: c = this .text[i];
109: if ((c == '\n') || (c == '\r')) {
110: eol = true;
111: break;
112: }
113: }
114:
115: nextChar = i;
116: if (eol) {
117: nextChar++;
118: if (c == '\r') {
119: if ((nextChar < nChars)
120: && (this .text[nextChar] == '\n')) {
121: nextChar++;
122: }
123: }
124: this .position = nextChar;
125: return (this .position);
126: }
127: }
128: }
129:
130: /**
131: * Same like next(), but returns the End-Of-Text as
132: * if there was a linebreak added (Reader.readLine() compatible)
133: *
134: * @return The next position.
135: */
136: public int nextWithEnd() {
137: final int pos = this .position;
138: if (pos == DONE) {
139: return DONE;
140: }
141: if (pos == this .text.length) {
142: this .position = DONE;
143: return DONE;
144: }
145: final int retval = nextPosition();
146: if (retval == DONE) {
147: return this .text.length;
148: }
149: return retval;
150: }
151:
152: /**
153: * Returns the text to be broken up.
154: *
155: * @return The text.
156: */
157: public String getText() {
158: return new String(this .text);
159: }
160:
161: /**
162: * Sets the text to be broken up.
163: *
164: * @param text the text.
165: */
166: public void setText(final String text) {
167: this .position = 0;
168: this .text = text.toCharArray();
169: }
170:
171: /**
172: * Returns <tt>true</tt> if the iteration has more elements. (In other
173: * words, returns <tt>true</tt> if <tt>next</tt> would return an element
174: * rather than throwing an exception.)
175: *
176: * @return <tt>true</tt> if the iterator has more elements.
177: */
178: public boolean hasNext() {
179: return (this .position != DONE);
180: }
181:
182: /**
183: * Returns the next element in the iteration.
184: *
185: * @return the next element in the iteration.
186: */
187: public Object next() {
188: if (this .position == DONE) {
189: // allready at the end ...
190: return null;
191: }
192:
193: final int lastFound = this .position;
194: int pos = nextWithEnd();
195: if (pos == DONE) {
196: // the end of the text has been reached ...
197: return new String(this .text, lastFound, this .text.length
198: - lastFound);
199: }
200:
201: // step one char back
202: if (pos > 0) {
203: final int end = lastFound;
204: for (; ((pos) > end)
205: && ((this .text[pos - 1] == '\n') || this .text[pos - 1] == '\r'); pos--) {
206: // search the end of the current linebreak sequence ..
207: }
208: }
209: //System.out.println ("text: " + new String (text));
210: //System.out.println ("pos: " + pos + " lastFound: " + lastFound);
211: return new String(this .text, lastFound, pos - lastFound);
212: }
213:
214: /**
215: *
216: * Removes from the underlying collection the last element returned by the
217: * iterator (optional operation). This method can be called only once per
218: * call to <tt>next</tt>. The behavior of an iterator is unspecified if
219: * the underlying collection is modified while the iteration is in
220: * progress in any way other than by calling this method.
221: *
222: * @exception UnsupportedOperationException if the <tt>remove</tt>
223: * operation is not supported by this Iterator.
224: * @exception IllegalStateException if the <tt>next</tt> method has not
225: * yet been called, or the <tt>remove</tt> method has already
226: * been called after the last call to the <tt>next</tt>
227: * method.
228: */
229: public void remove() {
230: throw new UnsupportedOperationException(
231: "This iterator is read-only.");
232: }
233: }
|