001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.mif;
017:
018: import com.vividsolutions.jts.io.ParseException;
019:
020: /**
021: * Simple tokenizer class
022: *
023: * @author Luca S. Percich, AMA-MI
024: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/mif/src/main/java/org/geotools/data/mif/MIFStringTokenizer.java $
025: * @version $Id: MIFStringTokenizer.java 29429 2008-02-23 10:01:04Z aaime $
026: */
027: public class MIFStringTokenizer {
028: private String line = ""; // Current line buffer
029: private String lastToken = null; // Current extracted token
030:
031: /**
032: * Builds a tokenizer
033: */
034: public MIFStringTokenizer() {
035: super ();
036: }
037:
038: /**
039: * "Reads" a line from the given line, and initializes the token.
040: *
041: * @param line
042: *
043: * @return true if could read a non empty line (i.e. line != "")
044: */
045: public boolean readLine(String line) {
046:
047: if (line == null) {
048: this .line = "";
049: } else {
050: this .line = ltrim(line);
051: }
052:
053: return (!line.equals(""));
054: }
055:
056: /**
057: * Tries to read a line from the input buffer (if any) and store it in the
058: * line buffer
059: *
060: * @return True if a non-null string was read
061: */
062: public boolean readLine() {
063: return readLine("");
064: }
065:
066: /**
067: * Cuts the first token from line buffer using the given separator, taking
068: * in to account string delimiters if needed <br>
069: * Strings might be delimited by double quotes. Escaping char is a double
070: * quote, i.e. "\"" becomes """".
071: *
072: * @param separator Character used as token separator.
073: * @param nextLineIfEmpty If the returned token is empty, try to read it
074: * from the next line.
075: * @param quotedStrings If true, expects a quoted string and read it,
076: * otherwise treats the double quotes as a normal char.
077: *
078: * @return The parsed token
079: *
080: * @throws ParseException DOCUMENT ME!
081: */
082: public String getToken(char separator, boolean nextLineIfEmpty,
083: boolean quotedStrings) throws ParseException {
084:
085: String token = "";
086:
087: if (lastToken != null) {
088: token = lastToken;
089: lastToken = null;
090: return token;
091: }
092:
093: line = ltrim(line);
094:
095: if (line.equals("") && nextLineIfEmpty) {
096: readLine();
097: }
098:
099: if (line.equals("")) {
100: return "";
101: }
102:
103: int index = -1;
104:
105: if (quotedStrings && line.startsWith("\"")) {
106: try {
107: index = 1;
108:
109: boolean loop = true;
110: int len = line.length();
111:
112: while (loop) {
113: while ((index < len) && (line.charAt(index) != '"'))
114: index++;
115:
116: if ((index < (len - 2))
117: && (line.charAt(index) == '"')
118: && (line.charAt(index + 1) == separator)) {
119: loop = false;
120: } else if ((index == (len - 1))
121: && (line.charAt(index) == '"')) {
122: loop = false;
123: } else {
124: index++;
125: }
126: }
127:
128: token = line.substring(1, index).replaceAll("\"\"",
129: "\"");
130: line = ltrim(line.substring(index + 1));
131:
132: if (line.length() > 0) {
133: if (line.charAt(0) == separator) {
134: line = line.substring(1);
135: } else {
136: if (separator != ' ')
137: throw new ParseException("Bad separator");
138: }
139: }
140: } catch (Exception e) {
141: throw new ParseException("Error reading quoted string");
142: }
143: } else {
144: index = line.indexOf(separator);
145:
146: if (index == -1) {
147: token = line;
148: line = "";
149: } else {
150: token = ltrim(line.substring(0, index));
151: line = ltrim(line.substring(index + 1));
152: }
153: }
154:
155: return token;
156: }
157:
158: /**
159: * DOCUMENT ME!
160: *
161: * @param separator DOCUMENT ME!
162: * @param nextLineIfEmpty DOCUMENT ME!
163: *
164: * @return DOCUMENT ME!
165: *
166: * @throws ParseException DOCUMENT ME!
167: */
168: protected String getToken(char separator, boolean nextLineIfEmpty)
169: throws ParseException {
170: return getToken(separator, nextLineIfEmpty, false);
171: }
172:
173: /**
174: * DOCUMENT ME!
175: *
176: * @param separator DOCUMENT ME!
177: *
178: * @return DOCUMENT ME!
179: *
180: * @throws ParseException DOCUMENT ME!
181: */
182: protected String getToken(char separator) throws ParseException {
183: return getToken(separator, false, false);
184: }
185:
186: /**
187: * DOCUMENT ME!
188: *
189: * @return DOCUMENT ME!
190: *
191: * @throws ParseException DOCUMENT ME!
192: */
193: protected String getToken() throws ParseException {
194: return getToken(' ', false, false);
195: }
196:
197: /**
198: * Puts a token back to the input buffer so that the next call to getToken will
199: * return this token
200: * @param tok The token which has to be put back in the input buffer
201: */
202: public void putToken(String tok) {
203: lastToken = tok;
204: }
205:
206: /**
207: * DOCUMENT ME!
208: *
209: * @param unquoted DOCUMENT ME!
210: *
211: * @return DOCUMENT ME!
212: */
213: public static String strQuote(String unquoted) {
214: return "\"" + unquoted.replaceAll("\"", "\"\"") + "\"";
215: }
216:
217: /**
218: * DOCUMENT ME!
219: *
220: * @param quoted DOCUMENT ME!
221: *
222: * @return DOCUMENT ME!
223: */
224: public static String strUnquote(String quoted) {
225: if (quoted.startsWith("\"") && quoted.endsWith("\"")
226: && (quoted.length() > 1)) {
227: quoted = quoted.substring(1, quoted.length() - 1)
228: .replaceAll("\"\"", "\"");
229: }
230:
231: return quoted;
232: }
233:
234: // Can't use String.trim() when Delimiter is \t
235: // TODO use stringBuffer and a better algorithm
236: public static String ltrim(String untrimmed) {
237: while ((untrimmed.length() > 0) && (untrimmed.charAt(0) == ' ')) {
238: untrimmed = untrimmed.substring(1);
239: }
240:
241: return untrimmed;
242: }
243:
244: /**
245: * DOCUMENT ME!
246: *
247: * @return DOCUMENT ME!
248: */
249: public String getLine() {
250: return line;
251: }
252:
253: /**
254: * Check for non-empty line buffer
255: *
256: * @return true if current line buffer is not empty
257: */
258: public boolean isEmpty() {
259: return line.equals("");
260: }
261: }
|