001: package org.ofbiz.rules.parse;
002:
003: import java.util.*;
004:
005: /**
006: * <p><b>Title:</b> Track
007: * <p><b>Description:</b> None
008: * <p>Copyright (c) 1999 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: * A Track is a sequence that throws a <code>
031: * TrackException</code> if the sequence begins but
032: * does not complete.
033: *
034: * @author Steven J. Metsker
035: * @version 1.0
036: */
037:
038: public class Track extends Sequence {
039:
040: /**
041: * Constructs a nameless Track.
042: */
043: public Track() {
044: }
045:
046: /**
047: * Constructs a Track with the given name.
048: *
049: * @param name a name to be known by
050: */
051: public Track(String name) {
052: super (name);
053: }
054:
055: /**
056: * Given a collection of assemblies, this method matches
057: * this track against all of them, and returns a new
058: * collection of the assemblies that result from the
059: * matches.
060: *
061: * If the match begins but does not complete, this method
062: * throws a <code>TrackException</code>.
063: *
064: * @return a List of assemblies that result from matching
065: * against a beginning set of assemblies
066: *
067: * @param in a vector of assemblies to match against
068: *
069: */
070: public List match(List in) {
071: boolean inTrack = false;
072: List last = in;
073: List out = in;
074: Enumeration e = Collections.enumeration(subparsers);
075:
076: while (e.hasMoreElements()) {
077: Parser p = (Parser) e.nextElement();
078:
079: out = p.matchAndAssemble(last);
080: if (out.isEmpty()) {
081: if (inTrack) {
082: throwTrackException(last, p);
083: }
084: return out;
085: }
086: inTrack = true;
087: last = out;
088: }
089: return out;
090: }
091:
092: /**
093: * Throw an exception showing how far the match had
094: * progressed, what it found next, and what it was
095: * expecting.
096: */
097: protected void throwTrackException(List previousState, Parser p) {
098:
099: Assembly best = best(previousState);
100: String after = best.consumed(" ");
101:
102: if (after.equals("")) {
103: after = "-nothing-";
104: }
105:
106: String expected = p.toString();
107:
108: Object next = best.peek();
109: String found = (next == null) ? "-nothing-" : next.toString();
110:
111: throw new TrackException(after, expected, found);
112: }
113: }
|