1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xml.dtm.ref;
  58. import org.apache.xml.dtm.*;
  59. import org.w3c.dom.Node;
  60. import org.w3c.dom.DOMException;
  61. /**
  62. * <code>DTMNodeList</code> gives us an implementation of the DOM's
  63. * NodeList interface wrapped around a DTM Iterator. The author
  64. * considers this something of an abominations, since NodeList was not
  65. * intended to be a general purpose "list of nodes" API and is
  66. * generally considered by the DOM WG to have be a mistake... but I'm
  67. * told that some of the XPath/XSLT folks say they must have this
  68. * solution.
  69. *
  70. * Please note that this is not necessarily equivlaent to a DOM
  71. * NodeList operating over the same document. In particular:
  72. * <ul>
  73. *
  74. * <li>If there are several Text nodes in logical succession (ie,
  75. * across CDATASection and EntityReference boundaries), we will return
  76. * only the first; the caller is responsible for stepping through
  77. * them.
  78. * (%REVIEW% Provide a convenience routine here to assist, pending
  79. * proposed DOM Level 3 getAdjacentText() operation?) </li>
  80. *
  81. * <li>Since the whole XPath/XSLT architecture assumes that the source
  82. * document is not altered while we're working with it, we do not
  83. * promise to implement the DOM NodeList's "live view" response to
  84. * document mutation. </li>
  85. *
  86. * </ul>
  87. *
  88. * <p>State: In progress!!</p>
  89. * */
  90. public class DTMNodeList implements org.w3c.dom.NodeList
  91. {
  92. private DTMIterator dtm_iter;
  93. private boolean valid=true;
  94. private int m_firstChild;
  95. private DTM m_parentDTM;
  96. //================================================================
  97. // Methods unique to this class
  98. /** Public constructor: Wrap a DTMNodeList around an existing
  99. * and preconfigured DTMIterator
  100. *
  101. * WARNING: THIS HAS THE SIDE EFFECT OF ISSUING setShouldCacheNodes(true)
  102. * AGAINST THE DTMIterator.
  103. * */
  104. public DTMNodeList(DTMIterator dtmIterator)
  105. {
  106. int pos = dtmIterator.getCurrentPos();
  107. try
  108. {
  109. dtm_iter=(DTMIterator)dtmIterator.cloneWithReset();
  110. }
  111. catch(CloneNotSupportedException cnse) {}
  112. dtm_iter.setShouldCacheNodes(true);
  113. dtm_iter.runTo(-1);
  114. dtm_iter.setCurrentPos(pos);
  115. }
  116. /** Public constructor: Create a NodeList to support
  117. * DTMNodeProxy.getChildren().
  118. *
  119. * Unfortunately AxisIterators and DTMIterators don't share an API,
  120. * so I can't use the existing Axis.CHILD iterator. Rather than
  121. * create Yet Another Class, let's set up a special case of this
  122. * one.
  123. *
  124. * @param parentDTM The DTM containing this node
  125. * @param parentHandle DTM node-handle integer
  126. * */
  127. public DTMNodeList(DTM parentDTM,int parentHandle)
  128. {
  129. dtm_iter=null;
  130. m_parentDTM=parentDTM;
  131. m_firstChild=parentDTM.getFirstChild(parentHandle);
  132. }
  133. /** Access the wrapped DTMIterator. I'm not sure whether anyone will
  134. * need this or not, but let's write it and think about it.
  135. * */
  136. DTMIterator getDTMIterator()
  137. {
  138. return dtm_iter;
  139. }
  140. //================================================================
  141. // org.w3c.dom.NodeList API follows
  142. /**
  143. * Returns the <code>index</code>th item in the collection. If
  144. * <code>index</code> is greater than or equal to the number of nodes in
  145. * the list, this returns <code>null</code>.
  146. * @param indexIndex into the collection.
  147. * @return The node at the <code>index</code>th position in the
  148. * <code>NodeList</code>, or <code>null</code> if that is not a valid
  149. * index.
  150. */
  151. public Node item(int index)
  152. {
  153. if(dtm_iter!=null)
  154. {
  155. int handle=dtm_iter.item(index);
  156. return dtm_iter.getDTM(handle).getNode(handle);
  157. }
  158. else
  159. {
  160. int handle=m_firstChild;
  161. while(--index>=0 && handle!=DTM.NULL)
  162. handle=m_parentDTM.getNextSibling(handle);
  163. return m_parentDTM.getNode(handle);
  164. }
  165. }
  166. /**
  167. * The number of nodes in the list. The range of valid child node indices
  168. * is 0 to <code>length-1</code> inclusive.
  169. */
  170. public int getLength()
  171. {
  172. if(dtm_iter!=null)
  173. {
  174. return dtm_iter.getLength();
  175. }
  176. else
  177. {
  178. int count=0;
  179. for(int handle=m_firstChild;
  180. handle!=DTM.NULL;
  181. handle=m_parentDTM.getNextSibling(handle))
  182. ++count;
  183. return count;
  184. }
  185. }
  186. }