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. import org.w3c.dom.traversal.*;
  62. /**
  63. * <code>DTMNodeIterator</code> gives us an implementation of the
  64. * DTMNodeIterator which returns DOM nodes.
  65. *
  66. * Please note that this is not necessarily equivlaent to a DOM
  67. * NodeIterator operating over the same document. In particular:
  68. * <ul>
  69. *
  70. * <li>If there are several Text nodes in logical succession (ie,
  71. * across CDATASection and EntityReference boundaries), we will return
  72. * only the first; the caller is responsible for stepping through
  73. * them.
  74. * (%REVIEW% Provide a convenience routine here to assist, pending
  75. * proposed DOM Level 3 getAdjacentText() operation?) </li>
  76. *
  77. * <li>Since the whole XPath/XSLT architecture assumes that the source
  78. * document is not altered while we're working with it, we do not
  79. * promise to implement the DOM NodeIterator's "maintain current
  80. * position" response to document mutation. </li>
  81. *
  82. * <li>Since our design for XPath NodeIterators builds a stateful
  83. * filter directly into the traversal object, getNodeFilter() is not
  84. * supported.</li>
  85. *
  86. * </ul>
  87. *
  88. * <p>State: In progress!!</p>
  89. * */
  90. public class DTMNodeIterator implements org.w3c.dom.traversal.NodeIterator
  91. {
  92. private DTMIterator dtm_iter;
  93. private boolean valid=true;
  94. //================================================================
  95. // Methods unique to this class
  96. /** Public constructor: Wrap a DTMNodeIterator around an existing
  97. * and preconfigured DTMIterator
  98. * */
  99. public DTMNodeIterator(DTMIterator dtmIterator)
  100. {
  101. try
  102. {
  103. dtm_iter=(DTMIterator)dtmIterator.clone();
  104. }
  105. catch(CloneNotSupportedException cnse)
  106. {
  107. throw new org.apache.xml.utils.WrappedRuntimeException(cnse);
  108. }
  109. }
  110. /** Access the wrapped DTMIterator. I'm not sure whether anyone will
  111. * need this or not, but let's write it and think about it.
  112. * */
  113. public DTMIterator getDTMIterator()
  114. {
  115. return dtm_iter;
  116. }
  117. //================================================================
  118. // org.w3c.dom.traversal.NodeFilter API follows
  119. /** Detaches the NodeIterator from the set which it iterated over,
  120. * releasing any computational resources and placing the iterator in
  121. * the INVALID state.
  122. * */
  123. public void detach()
  124. {
  125. // Theoretically, we could release dtm_iter at this point. But
  126. // some of the operations may still want to consult it even though
  127. // navigation is now invalid.
  128. valid=false;
  129. }
  130. /** The value of this flag determines whether the children
  131. * of entity reference nodes are visible to the iterator.
  132. *
  133. * @return false, always (the DTM model flattens entity references)
  134. * */
  135. public boolean getExpandEntityReferences()
  136. {
  137. return false;
  138. }
  139. /** Return a handle to the filter used to screen nodes.
  140. *
  141. * This is ill-defined in Xalan's usage of Nodeiterator, where we have
  142. * built stateful XPath-based filtering directly into the traversal
  143. * object. We could return something which supports the NodeFilter interface
  144. * and allows querying whether a given node would be permitted if it appeared
  145. * as our next node, but in the current implementation that would be very
  146. * complex -- and just isn't all that useful.
  147. *
  148. * @throws DOMException -- NOT_SUPPORTED_ERROR because I can't think
  149. * of anything more useful to do in this case
  150. * */
  151. public NodeFilter getFilter()
  152. {
  153. throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
  154. }
  155. /** @return The root node of the NodeIterator, as specified
  156. * when it was created.
  157. * */
  158. public Node getRoot()
  159. {
  160. int handle=dtm_iter.getRoot();
  161. return dtm_iter.getDTM(handle).getNode(handle);
  162. }
  163. /** Return a mask describing which node types are presented via the
  164. * iterator.
  165. **/
  166. public int getWhatToShow()
  167. {
  168. return dtm_iter.getWhatToShow();
  169. }
  170. /** @return the next node in the set and advance the position of the
  171. * iterator in the set.
  172. *
  173. * @throw DOMException - INVALID_STATE_ERR Raised if this method is
  174. * called after the detach method was invoked.
  175. * */
  176. public Node nextNode() throws DOMException
  177. {
  178. if(!valid)
  179. throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
  180. int handle=dtm_iter.nextNode();
  181. if (handle==-1)
  182. return null;
  183. return dtm_iter.getDTM(handle).getNode(handle);
  184. }
  185. /** @return the next previous in the set and advance the position of the
  186. * iterator in the set.
  187. *
  188. * @throw DOMException - INVALID_STATE_ERR Raised if this method is
  189. * called after the detach method was invoked.
  190. * */
  191. public Node previousNode()
  192. {
  193. if(!valid)
  194. throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
  195. int handle=dtm_iter.previousNode();
  196. return dtm_iter.getDTM(handle).getNode(handle);
  197. }
  198. }