View Javadoc

1   /*
2    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
3    * 
4    * This software is open source. 
5    * See the bottom of this file for the licence.
6    * 
7    * $Id: ElementStack.java,v 1.12 2004/08/02 18:44:07 maartenc Exp $
8    */
9   
10  package org.dom4j.io;
11  
12  import org.dom4j.Element;
13  import org.dom4j.ElementHandler;
14  import org.dom4j.ElementPath;
15  
16  /*** <p><code>ElementStack</code> is used internally inside the 
17    * {@link SAXContentHandler} to maintain a stack of {@link Element} 
18    * instances. 
19    * It opens an integration possibility allowing derivations to prune the tree
20    * when a node is complete.</p>
21    *
22    * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
23    * @version $Revision: 1.12 $
24    */
25  class ElementStack implements ElementPath {
26  
27      /*** stack of <code>Element</code> objects */
28      protected Element[] stack;
29      
30      /*** index of the item at the top of the stack or -1 if the stack is empty */
31      protected int lastElementIndex = -1;
32      
33      private DispatchHandler handler = null;
34  
35      
36      public ElementStack() {
37          this(50);
38      }
39      
40      public ElementStack(int defaultCapacity) {
41          stack = new Element[defaultCapacity];
42      }
43      
44      public void setDispatchHandler(DispatchHandler handler)
45      {
46          this.handler = handler;   
47      }
48      
49      public DispatchHandler getDispatchHandler(){
50         return this.handler;
51      }
52      
53      /*** Peeks at the top element on the stack without changing the contents
54        * of the stack.
55        * 
56        * @return the current element on the stack 
57        */
58      public void clear() {
59          lastElementIndex = -1;
60      }
61      
62      /*** Peeks at the top element on the stack without changing the contents
63        * of the stack.
64        * 
65        * @return the current element on the stack 
66        */
67      public Element peekElement() {
68          if ( lastElementIndex < 0 ) { 
69              return null;
70          }
71          return stack[ lastElementIndex ];
72      }
73      
74      /*** Pops the element off the stack
75        *
76        * @return the element that has just been popped off the stack 
77        */
78      public Element popElement() {
79          if ( lastElementIndex < 0 ) { 
80              return null;
81          }
82          return stack[ lastElementIndex-- ];
83      }
84      
85      /*** Pushes a new element onto the stack
86        * 
87        * @return pushes the new element onto the stack and add it to its parent
88        * if there is one.
89        */
90      public void pushElement(Element element) {
91          int length = stack.length;
92          if ( ++lastElementIndex >= length ) {
93              reallocate( length * 2 );
94          }
95          stack[lastElementIndex] = element;
96      }
97      
98      /*** Reallocates the stack to the given size
99        */
100     protected void reallocate( int size ) {
101         Element[] oldStack = stack;
102         stack = new Element[ size ];
103         System.arraycopy( oldStack, 0, stack, 0, oldStack.length );
104     }
105     
106     // The ElementPath Interface
107     //
108     public int size()
109     {
110         return lastElementIndex + 1;
111     }
112     
113     public Element getElement(int depth)
114     {
115         Element element;
116         try {
117             element = (Element)stack[depth];   
118         }
119         catch (ArrayIndexOutOfBoundsException e)
120         {
121             element = null;   
122         }
123         return element;
124     }
125     
126     public String getPath()
127     {
128         if (handler == null) {
129             setDispatchHandler(new DispatchHandler());
130         }
131         return handler.getPath();
132     }
133     
134     public Element getCurrent()
135     {
136         return peekElement();   
137     }
138     
139     public void addHandler(String path, ElementHandler handler) {
140         this.handler.addHandler(getHandlerPath(path), handler);
141     }
142     
143     public void removeHandler(String path) {
144         this.handler.removeHandler(getHandlerPath(path));
145     }
146     
147     /*** @return true when an <code>ElementHandler</code> is registered for
148       * the specified path.
149       */
150     public boolean containsHandler(String path) {
151         return this.handler.containsHandler(path);
152     }
153 
154     private String getHandlerPath(String path) {
155         String handlerPath;
156         if (this.handler == null) {
157             setDispatchHandler(new DispatchHandler());
158         }
159         if (path.startsWith("/")) {
160             handlerPath = path;   
161         }
162         else if (getPath().equals("/")) {
163             handlerPath = getPath() + path;
164         }
165         else {
166             handlerPath = getPath() + "/" + path;   
167         }
168         return handlerPath;
169     }
170 }
171 
172 
173 
174 
175 /*
176  * Redistribution and use of this software and associated documentation
177  * ("Software"), with or without modification, are permitted provided
178  * that the following conditions are met:
179  *
180  * 1. Redistributions of source code must retain copyright
181  *    statements and notices.  Redistributions must also contain a
182  *    copy of this document.
183  *
184  * 2. Redistributions in binary form must reproduce the
185  *    above copyright notice, this list of conditions and the
186  *    following disclaimer in the documentation and/or other
187  *    materials provided with the distribution.
188  *
189  * 3. The name "DOM4J" must not be used to endorse or promote
190  *    products derived from this Software without prior written
191  *    permission of MetaStuff, Ltd.  For written permission,
192  *    please contact dom4j-info@metastuff.com.
193  *
194  * 4. Products derived from this Software may not be called "DOM4J"
195  *    nor may "DOM4J" appear in their names without prior written
196  *    permission of MetaStuff, Ltd. DOM4J is a registered
197  *    trademark of MetaStuff, Ltd.
198  *
199  * 5. Due credit should be given to the DOM4J Project - 
200  *    http://www.dom4j.org
201  *
202  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
203  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
204  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
205  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
206  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
207  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
208  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
209  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
210  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
211  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
212  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
213  * OF THE POSSIBILITY OF SUCH DAMAGE.
214  *
215  * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
216  *
217  * $Id: ElementStack.java,v 1.12 2004/08/02 18:44:07 maartenc Exp $
218  */