001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015:
016: package org.griphyn.vdl.router;
017:
018: import org.griphyn.vdl.util.Logging;
019: import java.util.*;
020:
021: /**
022: * This class maintains a stack of classes that implement the
023: * {@link java.util.List} interface.
024: *
025: * @author Jens-S. Vöckler
026: * @author Yong Zhao
027: * @version $Revision $
028: */
029: public class ListStack {
030: /**
031: * Stores a reference to the underlying data as top-of-stack.
032: */
033: private Vector m_stack;
034:
035: /**
036: * C'tor: Creates a new stack instance that is empty.
037: */
038: public ListStack() {
039: this .m_stack = new Vector();
040: }
041:
042: /**
043: * Pushes a new bunch of things onto the stack.
044: * @param item is the new List to become new top-of-stack.
045: */
046: public void push(List item) {
047: int size = this .m_stack.size();
048: int logsize = (item == null ? 0 : item.size());
049: Logging.instance().log(
050: "stack",
051: 2,
052: "pushing " + logsize + " items into lstack[" + size
053: + ']');
054: this .m_stack.addElement(item);
055: }
056:
057: /**
058: * Removes the tos, thus makeing the next-lower vector the tos.
059: * @return the old top-of-stack.
060: * @throws EmptyStackException if the stack did not have any elements.
061: */
062: public List pop() {
063: int size = this .m_stack.size();
064: if (size == 0)
065: throw new EmptyStackException();
066:
067: Logging.instance().log("stack", 2,
068: "popping lstack[" + (size - 1) + ']');
069: return (List) this .m_stack.remove(size - 1);
070: }
071:
072: /**
073: * Accessor: Grants access to the top of stack (tos) element.
074: * @return the current top of stack vector.
075: * @throws EmptyStackException if the stack is empty.
076: */
077: public List tos() {
078: int size = this .m_stack.size();
079: if (size == 0)
080: throw new EmptyStackException();
081: return (List) this .m_stack.lastElement();
082: }
083:
084: /**
085: * Accessor predicate: Determines, if the stack contains any elements.
086: * @return true, if the stack is empty, false otherwise.
087: */
088: public boolean isEmpty() {
089: return (this .m_stack.size() == 0);
090: }
091:
092: /**
093: * Accessor: Determines the number of elements in the stack.
094: * @return number of elements, or 0 for an empty stack.
095: */
096: public int size() {
097: return this .m_stack.size();
098: }
099:
100: /**
101: * Accessor to a definition at a certain position. This method is
102: * susceptible to exception thrown by the <code>List</code> for
103: * inaccessible positions.
104: * @return List at a given position in the stack.
105: */
106: public List at(int index) {
107: return (List) this .m_stack.elementAt(index);
108: }
109:
110: /**
111: * Flattens all vectors in the stack into one, starting with the
112: * bottom-most vector.
113: * @return List containing all vectors, may be empty.
114: */
115: public List flatten() {
116: ArrayList result = new ArrayList();
117: for (int i = 0; i < this .m_stack.size(); ++i) {
118: result.addAll((List) this.m_stack.elementAt(i));
119: }
120: return result;
121: }
122: }
|