001: package org.ofbiz.rules.parse.tokens;
002:
003: import java.io.*;
004:
005: /**
006: * <p><b>Title:</b> Symbol Root Node
007: * <p><b>Description:</b> None
008: * <p>Copyright (c) 2000 Steven J. Metsker.
009: * <p>Copyright (c) 2001 The Open For Business Project - www.ofbiz.org
010: *
011: * <p>Permission is hereby granted, free of charge, to any person obtaining a
012: * copy of this software and associated documentation files (the "Software"),
013: * to deal in the Software without restriction, including without limitation
014: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
015: * and/or sell copies of the Software, and to permit persons to whom the
016: * Software is furnished to do so, subject to the following conditions:
017: *
018: * <p>The above copyright notice and this permission notice shall be included
019: * in all copies or substantial portions of the Software.
020: *
021: * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
022: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
023: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
024: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
025: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
026: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
027: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
028: *
029: * <br>
030: * This class is a special case of a <code>SymbolNode</code>. A
031: * <code>SymbolRootNode</code> object has no symbol of its
032: * own, but has children that represent all possible symbols.
033: *
034: * @author Steven J. Metsker
035: * @version 1.0
036: */
037: public class SymbolRootNode extends SymbolNode {
038: protected SymbolNode[] children = new SymbolNode[256];
039:
040: /**
041: * Create and initialize a root node.
042: */
043: public SymbolRootNode() {
044: super (null, (char) 0);
045: init();
046: }
047:
048: /**
049: * Add the given string as a symbol.
050: *
051: * @param String the character sequence to add
052: */
053: public void add(String s) {
054: char c = s.charAt(0);
055: SymbolNode n = ensureChildWithChar(c);
056:
057: n.addDescendantLine(s.substring(1));
058: findDescendant(s).setValid(true);
059: }
060:
061: /**
062: * A root node has no parent and no character of its own, so
063: * its ancestry is "".
064: *
065: * @return an empty string
066: */
067: public String ancestry() {
068: return "";
069: }
070:
071: /**
072: * A root node maintains its children in an array instead of
073: * a ArrayList, to be faster.
074: */
075: protected SymbolNode findChildWithChar(char c) {
076: return children[c];
077: }
078:
079: /**
080: * Set all possible symbols to be valid children. This means
081: * that the decision of which characters are valid one-
082: * character symbols lies outside this tree. If a tokenizer
083: * asks this tree to produce a symbol, this tree assumes that
084: * the first available character is a valid symbol.
085: */
086: protected void init() {
087: int len = children.length;
088:
089: for (char i = 0; i < len; i++) {
090: children[i] = new SymbolNode(this , i);
091: children[i].setValid(true);
092: }
093: }
094:
095: /**
096: * Return a symbol string from a reader.
097: *
098: * @param PushbackReader a reader to read from
099: *
100: * @param int the first character of this symbol, already
101: * read from the reader
102: *
103: * @return a symbol string from a reader
104: */
105: public String nextSymbol(PushbackReader r, int first)
106: throws IOException {
107:
108: SymbolNode n1 = findChildWithChar((char) first);
109: SymbolNode n2 = n1.deepestRead(r);
110: SymbolNode n3 = n2.unreadToValid(r);
111:
112: return n3.ancestry();
113: }
114: }
|