001: package org.ofbiz.rules.parse.tokens;
002:
003: import java.io.*;
004: import java.util.*;
005:
006: /**
007: * <p><b>Title:</b> Token String Source
008: * <p><b>Description:</b> None
009: * <p>Copyright (c) 1999 Steven J. Metsker.
010: * <p>Copyright (c) 2001 The Open For Business Project - www.ofbiz.org
011: *
012: * <p>Permission is hereby granted, free of charge, to any person obtaining a
013: * copy of this software and associated documentation files (the "Software"),
014: * to deal in the Software without restriction, including without limitation
015: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
016: * and/or sell copies of the Software, and to permit persons to whom the
017: * Software is furnished to do so, subject to the following conditions:
018: *
019: * <p>The above copyright notice and this permission notice shall be included
020: * in all copies or substantial portions of the Software.
021: *
022: * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
023: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
024: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
025: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
026: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
027: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
028: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
029: *
030: * <br>
031: * A TokenStringSource enumerates over a specified reader,
032: * returning TokenStrings delimited by a specified delimiter.
033: * <p>
034: * For example,
035: * <blockquote><pre>
036: *
037: * String s = "I came; I saw; I left in peace;";
038: *
039: * TokenStringSource tss =
040: * new TokenStringSource(new Tokenizer(s), ";");
041: *
042: * while (tss.hasMoreTokenStrings()) {
043: * System.out.println(tss.nextTokenString());
044: * }
045: *
046: * </pre></blockquote>
047: *
048: * prints out:
049: *
050: * <blockquote><pre>
051: * I came
052: * I saw
053: * I left in peace
054: * </pre></blockquote>
055: *
056: * @author Steven J. Metsker
057: * @version 1.0
058: */
059: public class TokenStringSource {
060: protected Tokenizer tokenizer;
061: protected String delimiter;
062: protected TokenString cachedTokenString = null;
063:
064: /**
065: * Constructs a TokenStringSource that will read TokenStrings
066: * using the specified tokenizer, delimited by the specified
067: * delimiter.
068: *
069: * @param tokenizer a tokenizer to read tokens from
070: *
071: * @param delimiter the character that fences off where one
072: * TokenString ends and the next begins
073: *
074: * @returns a TokenStringSource that will read TokenStrings
075: * from the specified tokenizer, delimited by the
076: * specified delimiter
077: */
078: public TokenStringSource(Tokenizer tokenizer, String delimiter) {
079:
080: this .tokenizer = tokenizer;
081: this .delimiter = delimiter;
082: }
083:
084: /**
085: * The design of <code>nextTokenString</code> is that is
086: * always returns a cached value. This method will (at least
087: * attempt to) load the cache if the cache is empty.
088: */
089: protected void ensureCacheIsLoaded() {
090: if (cachedTokenString == null) {
091: loadCache();
092: }
093: }
094:
095: /**
096: * Returns true if the source has more TokenStrings.
097: *
098: * @return true, if the source has more TokenStrings that
099: * have not yet been popped with <code>
100: * nextTokenString</code>.
101: */
102: public boolean hasMoreTokenStrings() {
103: ensureCacheIsLoaded();
104: return cachedTokenString != null;
105: }
106:
107: /**
108: * Loads the next TokenString into the cache, or sets the
109: * cache to null if the source is out of tokens.
110: */
111: protected void loadCache() {
112: List tokenVector = nextVector();
113:
114: if (tokenVector.isEmpty()) {
115: cachedTokenString = null;
116: } else {
117: Token tokens[] = (Token[]) tokenVector
118: .toArray(new Token[tokenVector.size()]);
119:
120: cachedTokenString = new TokenString(tokens);
121: }
122: }
123:
124: /**
125: * Shows the example in the class comment.
126: *
127: * @param args ignored
128: */
129: public static void main(String args[]) {
130:
131: String s = "I came; I saw; I left in peace;";
132:
133: TokenStringSource tss = new TokenStringSource(new Tokenizer(s),
134: ";");
135:
136: while (tss.hasMoreTokenStrings()) {
137: System.out.println(tss.nextTokenString());
138: }
139: }
140:
141: /**
142: * Returns the next TokenString from the source.
143: *
144: * @return the next TokenString from the source
145: */
146: public TokenString nextTokenString() {
147: ensureCacheIsLoaded();
148: TokenString returnTokenString = cachedTokenString;
149:
150: cachedTokenString = null;
151: return returnTokenString;
152: }
153:
154: /**
155: * Returns a List of the tokens in the source up to either
156: * the delimiter or the end of the source.
157: *
158: * @return a List of the tokens in the source up to either
159: * the delimiter or the end of the source.
160: */
161: protected List nextVector() {
162: List v = new ArrayList();
163:
164: try {
165: while (true) {
166: Token tok = tokenizer.nextToken();
167:
168: if (tok.ttype() == Token.TT_EOF
169: || tok.sval().equals(delimiter)) {
170:
171: break;
172: }
173: v.add(tok);
174: }
175: } catch (IOException e) {
176: throw new InternalError("Problem tokenizing string: " + e);
177: }
178: return v;
179: }
180: }
|