/*
* This file or a portion of this file is licensed under the terms of
* the Globus Toolkit Public License, found in file GTPL, or at
* http://www.globus.org/toolkit/download/license.html. This notice must
* appear in redistributions of this file, with or without modification.
*
* Redistributions of this Software, with or without modification, must
* reproduce the GTPL in: (1) the Software, or (2) the Documentation or
* some other similar material which is provided with the Software (if
* any).
*
* Copyright 1999-2004 University of Chicago and The University of
* Southern California. All rights reserved.
*/
package org.griphyn.vdl.router;
import org.griphyn.vdl.util.Logging;
import java.util.*;
/**
* This class maintains a stack of classes that implement the
* {@link java.util.List} interface.
*
* @author Jens-S. Vöckler
* @author Yong Zhao
* @version $Revision $
*/
public class ListStack
{
/**
* Stores a reference to the underlying data as top-of-stack.
*/
private Vector m_stack;
/**
* C'tor: Creates a new stack instance that is empty.
*/
public ListStack()
{
this.m_stack = new Vector();
}
/**
* Pushes a new bunch of things onto the stack.
* @param item is the new List to become new top-of-stack.
*/
public void push( List item )
{
int size = this.m_stack.size();
int logsize = ( item == null ? 0 : item.size() );
Logging.instance().log( "stack", 2, "pushing " + logsize +
" items into lstack[" + size + ']' );
this.m_stack.addElement(item);
}
/**
* Removes the tos, thus makeing the next-lower vector the tos.
* @return the old top-of-stack.
* @throws EmptyStackException if the stack did not have any elements.
*/
public List pop()
{
int size = this.m_stack.size();
if ( size == 0 ) throw new EmptyStackException();
Logging.instance().log( "stack", 2, "popping lstack[" + (size-1) + ']' );
return (List) this.m_stack.remove(size-1);
}
/**
* Accessor: Grants access to the top of stack (tos) element.
* @return the current top of stack vector.
* @throws EmptyStackException if the stack is empty.
*/
public List tos()
{
int size = this.m_stack.size();
if ( size == 0 ) throw new EmptyStackException();
return (List) this.m_stack.lastElement();
}
/**
* Accessor predicate: Determines, if the stack contains any elements.
* @return true, if the stack is empty, false otherwise.
*/
public boolean isEmpty()
{
return ( this.m_stack.size() == 0 );
}
/**
* Accessor: Determines the number of elements in the stack.
* @return number of elements, or 0 for an empty stack.
*/
public int size()
{
return this.m_stack.size();
}
/**
* Accessor to a definition at a certain position. This method is
* susceptible to exception thrown by the <code>List</code> for
* inaccessible positions.
* @return List at a given position in the stack.
*/
public List at( int index )
{
return (List) this.m_stack.elementAt(index);
}
/**
* Flattens all vectors in the stack into one, starting with the
* bottom-most vector.
* @return List containing all vectors, may be empty.
*/
public List flatten()
{
ArrayList result = new ArrayList();
for ( int i=0; i<this.m_stack.size(); ++i ) {
result.addAll((List) this.m_stack.elementAt(i));
}
return result;
}
}