View Javadoc

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