001: package org.ofbiz.rules.parse;
002:
003: import java.util.*;
004: import org.ofbiz.rules.utensil.*;
005:
006: /**
007: * <p><b>Title:</b> Assembly
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: * <p>An assembly maintains a stream of language elements along
032: * with stack and target objects.
033: *
034: * Parsers use assemblers to record progress at
035: * recognizing language elements from assembly's string.
036: *
037: * @author Steven J. Metsker
038: * @version 1.0
039: *
040: */
041: public abstract class Assembly implements Enumeration,
042: PubliclyCloneable {
043:
044: /**
045: * a place to keep track of consumption progress
046: */
047: protected Stack stack = new Stack();
048:
049: /** Another place to record progress; this is just an object.
050: * If a parser were recognizing an HTML page, for
051: * example, it might create a Page object early, and store it
052: * as an assembly's "target". As its recognition of the HTML
053: * progresses, it could use the stack to build intermediate
054: * results, like a heading, and then apply them to the target
055: * object.
056: */
057: protected PubliclyCloneable target;
058:
059: /**
060: * which element is next
061: */
062: protected int index = 0;
063:
064: /**
065: * Return a copy of this object.
066: *
067: * @return a copy of this object
068: */
069: public Object clone() {
070: try {
071: Assembly a = (Assembly) super .clone();
072:
073: a.stack = (Stack) stack.clone();
074: if (target != null) {
075: a.target = (PubliclyCloneable) target.clone();
076: }
077: return a;
078: } catch (CloneNotSupportedException e) {
079: // this shouldn't happen, since we are Cloneable
080: throw new InternalError();
081: }
082: }
083:
084: /**
085: * Returns the elements of the assembly that have been
086: * consumed, separated by the specified delimiter.
087: *
088: * @param String the mark to show between consumed
089: * elements
090: *
091: * @return the elements of the assembly that have been
092: * consumed
093: */
094: public abstract String consumed(String delimiter);
095:
096: /**
097: * Returns the default string to show between elements.
098: *
099: * @return the default string to show between elements
100: */
101: public abstract String defaultDelimiter();
102:
103: /**
104: * Returns the number of elements that have been consumed.
105: *
106: * @return the number of elements that have been consumed
107: */
108: public int elementsConsumed() {
109: return index;
110: }
111:
112: /**
113: * Returns the number of elements that have not been consumed.
114: *
115: * @return the number of elements that have not been
116: * consumed
117: */
118: public int elementsRemaining() {
119: return length() - elementsConsumed();
120: }
121:
122: /**
123: * Removes this assembly's stack.
124: *
125: * @return this assembly's stack
126: */
127: public Stack getStack() {
128: return stack;
129: }
130:
131: /**
132: * Returns the object identified as this assembly's "target".
133: * Clients can set and retrieve a target, which can be a
134: * convenient supplement as a place to work, in addition to
135: * the assembly's stack. For example, a parser for an
136: * HTML file might use a web page object as its "target". As
137: * the parser recognizes markup commands like <head>, it
138: * could apply its findings to the target.
139: *
140: * @return the target of this assembly
141: */
142: public Object getTarget() {
143: return target;
144: }
145:
146: /**
147: * Returns true if this assembly has unconsumed elements.
148: *
149: * @return true, if this assembly has unconsumed elements
150: */
151: public boolean hasMoreElements() {
152: return elementsConsumed() < length();
153: }
154:
155: /**
156: * Returns the number of elements in this assembly.
157: *
158: * @return the number of elements in this assembly
159: */
160: public abstract int length();
161:
162: /**
163: * Shows the next object in the assembly, without removing it
164: *
165: * @return the next object
166: *
167: */
168: public abstract Object peek();
169:
170: /**
171: * Removes the object at the top of this assembly's stack and
172: * returns it.
173: *
174: * @return the object at the top of this assembly's stack
175: *
176: * @exception EmptyStackException if this stack is empty
177: */
178: public Object pop() {
179: return stack.pop();
180: }
181:
182: /**
183: * Pushes an object onto the top of this assembly's stack.
184: *
185: * @param object the object to be pushed
186: */
187: public void push(Object o) {
188: stack.push(o);
189: }
190:
191: /**
192: * Returns the elements of the assembly that remain to be
193: * consumed, separated by the specified delimiter.
194: *
195: * @param String the mark to show between unconsumed
196: * elements
197: *
198: * @return the elements of the assembly that remain to be
199: * consumed
200: */
201: public abstract String remainder(String delimiter);
202:
203: /**
204: * Sets the target for this assembly. Targets must implement
205: * <code>clone()</code> as a public method.
206: *
207: * @param target a publicly cloneable object
208: */
209: public void setTarget(PubliclyCloneable target) {
210: this .target = target;
211: }
212:
213: /**
214: * Returns true if this assembly's stack is empty.
215: *
216: * @return true, if this assembly's stack is empty
217: */
218: public boolean stackIsEmpty() {
219: return stack.isEmpty();
220: }
221:
222: /**
223: * Returns a textual description of this assembly.
224: *
225: * @return a textual description of this assembly
226: */
227: public String toString() {
228: String delimiter = defaultDelimiter();
229:
230: return stack + consumed(delimiter) + "^" + remainder(delimiter);
231: }
232:
233: /**
234: * Put back n objects
235: *
236: */
237: public void unget(int n) {
238: index -= n;
239: if (index < 0) {
240: index = 0;
241: }
242: }
243: }
|