001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: ObjectStack.java 1225426 2011-12-29 04:13:08Z mrglavas $
020     */
021    package org.apache.xml.utils;
022    
023    import java.util.EmptyStackException;
024    
025    /**
026     * Implement a stack of simple integers.
027     *
028     * %OPT%
029     * This is currently based on ObjectVector, which permits fast acess but pays a
030     * heavy recopying penalty if/when its size is increased. If we expect deep
031     * stacks, we should consider a version based on ChunkedObjectVector.
032     * @xsl.usage internal
033     */
034    public class ObjectStack extends ObjectVector
035    {
036    
037      /**
038       * Default constructor.  Note that the default
039       * block size is very small, for small lists.
040       */
041      public ObjectStack()
042      {
043        super();
044      }
045    
046      /**
047       * Construct a ObjectVector, using the given block size.
048       *
049       * @param blocksize Size of block to allocate
050       */
051      public ObjectStack(int blocksize)
052      {
053        super(blocksize);
054      }
055    
056      /**
057       * Copy constructor for ObjectStack
058       * 
059       * @param v ObjectStack to copy
060       */
061      public ObjectStack (ObjectStack v)
062      {
063            super(v);
064      }
065      
066      /**
067       * Pushes an item onto the top of this stack.
068       *
069       * @param   i   the int to be pushed onto this stack.
070       * @return  the <code>item</code> argument.
071       */
072      public Object push(Object i)
073      {
074    
075        if ((m_firstFree + 1) >= m_mapSize)
076        {
077          m_mapSize += m_blocksize;
078    
079          Object newMap[] = new Object[m_mapSize];
080    
081          System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
082    
083          m_map = newMap;
084        }
085    
086        m_map[m_firstFree] = i;
087    
088        m_firstFree++;
089    
090        return i;
091      }
092    
093      /**
094       * Removes the object at the top of this stack and returns that
095       * object as the value of this function.
096       *
097       * @return     The object at the top of this stack.
098       */
099      public Object pop()
100      {
101        Object val = m_map[--m_firstFree];
102        m_map[m_firstFree] = null;
103        
104        return val;
105      }
106    
107      /**
108       * Quickly pops a number of items from the stack.
109       */
110    
111      public void quickPop(int n)
112      {
113        m_firstFree -= n;
114      }
115    
116      /**
117       * Looks at the object at the top of this stack without removing it
118       * from the stack.
119       *
120       * @return     the object at the top of this stack.
121       * @throws  EmptyStackException  if this stack is empty.
122       */
123      public Object peek()
124      {
125        try {
126          return m_map[m_firstFree - 1];
127        }
128        catch (ArrayIndexOutOfBoundsException e)
129        {
130          throw new EmptyStackException();
131        }
132      }
133    
134      /**
135       * Looks at the object at the position the stack counting down n items.
136       *
137       * @param n The number of items down, indexed from zero.
138       * @return     the object at n items down.
139       * @throws  EmptyStackException  if this stack is empty.
140       */
141      public Object peek(int n)
142      {
143        try {
144          return m_map[m_firstFree-(1+n)];
145        }
146        catch (ArrayIndexOutOfBoundsException e)
147        {
148          throw new EmptyStackException();
149        }
150      }
151    
152      /**
153       * Sets an object at a the top of the statck
154       *
155       *
156       * @param val object to set at the top
157       * @throws  EmptyStackException  if this stack is empty.
158       */
159      public void setTop(Object val)
160      {
161        try {
162          m_map[m_firstFree - 1] = val;
163        }
164        catch (ArrayIndexOutOfBoundsException e)
165        {
166          throw new EmptyStackException();
167        }
168      }
169    
170      /**
171       * Tests if this stack is empty.
172       *
173       * @return  <code>true</code> if this stack is empty;
174       *          <code>false</code> otherwise.
175       * @since   JDK1.0
176       */
177      public boolean empty()
178      {
179        return m_firstFree == 0;
180      }
181    
182      /**
183       * Returns where an object is on this stack.
184       *
185       * @param   o   the desired object.
186       * @return  the distance from the top of the stack where the object is]
187       *          located; the return value <code>-1</code> indicates that the
188       *          object is not on the stack.
189       * @since   JDK1.0
190       */
191      public int search(Object o)
192      {
193    
194        int i = lastIndexOf(o);
195    
196        if (i >= 0)
197        {
198          return size() - i;
199        }
200    
201        return -1;
202      }
203    
204      /**
205       * Returns clone of current ObjectStack
206       * 
207       * @return clone of current ObjectStack
208       */
209      public Object clone()
210        throws CloneNotSupportedException
211      {
212            return (ObjectStack) super.clone();
213      }  
214      
215    }