001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.car;
007:
008: import java.io.StringWriter;
009: import java.io.PrintWriter;
010: import java.util.Iterator;
011: import java.util.LinkedList;
012:
013: /**
014: Holds onto a set of String path elements to assist with tracking where in
015: an XML structure SAX processing is currently working. So an XML structure
016: like the following would have a path of "<top>", "<next>", "<more>" when SAX
017: processing issued a startElement event call for the "more" element.
018: <code>
019: <top>
020: <next>
021: <more>
022: ...
023: </code>
024:
025: Use the fromXML method to create from a more visually symbolic view of
026: what the path represents.
027: */
028: public class Path {
029: public static final String RCS_ID = "@(#) $Header$";
030: private LinkedList list = new LinkedList();
031:
032: /**
033: Create a new empty path.
034: */
035: public Path() {
036: }
037:
038: private static final int OUT_OF_TAG = 0;
039: private static final int IN_TAG = 1;
040:
041: public static Path fromTag(String tagName) {
042: return fromXML("<" + tagName + ">");
043: }
044:
045: /**
046: Creates a Path from the XML structured snippet. The following call
047: would create a path that contained "top", "next", and "more" in that
048: order.
049: */
050: public static Path fromXML(String xmlPath) {
051: Path path = new Path();
052:
053: if (xmlPath == null)
054: return path;
055:
056: int state = OUT_OF_TAG;
057: StringBuffer label = new StringBuffer();
058:
059: for (int i = 0; i < xmlPath.length(); i++) {
060: char c = xmlPath.charAt(i);
061:
062: if (state == OUT_OF_TAG) {
063: if (c == '<')
064: state = IN_TAG;
065: } else // in tag
066: {
067: if (c == '>') {
068: state = OUT_OF_TAG;
069: path.append(label.toString());
070: label.delete(0, label.length());
071: } else
072: label.append(c);
073: }
074: }
075: return path;
076: }
077:
078: /**
079: Add an item to the path.
080: */
081: public Path append(String item) {
082: if (item != null)
083: list.add(item);
084: return this ;
085: }
086:
087: /**
088: Remove the last item off of the path.
089: */
090: public String removeLast() {
091: if (list.size() > 0)
092: return (String) list.removeLast();
093: return null;
094: }
095:
096: /**
097: Returns true if the passed in object is a path with the same number of
098: path items and all strings in the two paths are equal.
099: */
100: public boolean equals(Object o) {
101: if (!(o instanceof Path))
102: return false;
103:
104: return list.equals(((Path) o).list);
105: }
106:
107: public String toString() {
108: StringWriter sw = new StringWriter();
109: PrintWriter pw = new PrintWriter(sw);
110:
111: for (Iterator i = list.iterator(); i.hasNext();)
112: pw.print("<" + i.next() + ">");
113: pw.flush();
114: return sw.toString();
115: }
116: }
|