1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: DTMNodeIterator.java,v 1.9 2004/02/16 23:06:11 minchau Exp $
  18. */
  19. package com.sun.org.apache.xml.internal.dtm.ref;
  20. import com.sun.org.apache.xml.internal.dtm.DTM;
  21. import com.sun.org.apache.xml.internal.dtm.DTMDOMException;
  22. import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  23. import org.w3c.dom.DOMException;
  24. import org.w3c.dom.Node;
  25. import org.w3c.dom.traversal.NodeFilter;
  26. /**
  27. * <code>DTMNodeIterator</code> gives us an implementation of the
  28. * DTMNodeIterator which returns DOM nodes.
  29. *
  30. * Please note that this is not necessarily equivlaent to a DOM
  31. * NodeIterator operating over the same document. In particular:
  32. * <ul>
  33. *
  34. * <li>If there are several Text nodes in logical succession (ie,
  35. * across CDATASection and EntityReference boundaries), we will return
  36. * only the first; the caller is responsible for stepping through
  37. * them.
  38. * (%REVIEW% Provide a convenience routine here to assist, pending
  39. * proposed DOM Level 3 getAdjacentText() operation?) </li>
  40. *
  41. * <li>Since the whole XPath/XSLT architecture assumes that the source
  42. * document is not altered while we're working with it, we do not
  43. * promise to implement the DOM NodeIterator's "maintain current
  44. * position" response to document mutation. </li>
  45. *
  46. * <li>Since our design for XPath NodeIterators builds a stateful
  47. * filter directly into the traversal object, getNodeFilter() is not
  48. * supported.</li>
  49. *
  50. * </ul>
  51. *
  52. * <p>State: In progress!!</p>
  53. * */
  54. public class DTMNodeIterator implements org.w3c.dom.traversal.NodeIterator
  55. {
  56. private DTMIterator dtm_iter;
  57. private boolean valid=true;
  58. //================================================================
  59. // Methods unique to this class
  60. /** Public constructor: Wrap a DTMNodeIterator around an existing
  61. * and preconfigured DTMIterator
  62. * */
  63. public DTMNodeIterator(DTMIterator dtmIterator)
  64. {
  65. try
  66. {
  67. dtm_iter=(DTMIterator)dtmIterator.clone();
  68. }
  69. catch(CloneNotSupportedException cnse)
  70. {
  71. throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(cnse);
  72. }
  73. }
  74. /** Access the wrapped DTMIterator. I'm not sure whether anyone will
  75. * need this or not, but let's write it and think about it.
  76. * */
  77. public DTMIterator getDTMIterator()
  78. {
  79. return dtm_iter;
  80. }
  81. //================================================================
  82. // org.w3c.dom.traversal.NodeFilter API follows
  83. /** Detaches the NodeIterator from the set which it iterated over,
  84. * releasing any computational resources and placing the iterator in
  85. * the INVALID state.
  86. * */
  87. public void detach()
  88. {
  89. // Theoretically, we could release dtm_iter at this point. But
  90. // some of the operations may still want to consult it even though
  91. // navigation is now invalid.
  92. valid=false;
  93. }
  94. /** The value of this flag determines whether the children
  95. * of entity reference nodes are visible to the iterator.
  96. *
  97. * @return false, always (the DTM model flattens entity references)
  98. * */
  99. public boolean getExpandEntityReferences()
  100. {
  101. return false;
  102. }
  103. /** Return a handle to the filter used to screen nodes.
  104. *
  105. * This is ill-defined in Xalan's usage of Nodeiterator, where we have
  106. * built stateful XPath-based filtering directly into the traversal
  107. * object. We could return something which supports the NodeFilter interface
  108. * and allows querying whether a given node would be permitted if it appeared
  109. * as our next node, but in the current implementation that would be very
  110. * complex -- and just isn't all that useful.
  111. *
  112. * @throws DOMException -- NOT_SUPPORTED_ERROR because I can't think
  113. * of anything more useful to do in this case
  114. * */
  115. public NodeFilter getFilter()
  116. {
  117. throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
  118. }
  119. /** @return The root node of the NodeIterator, as specified
  120. * when it was created.
  121. * */
  122. public Node getRoot()
  123. {
  124. int handle=dtm_iter.getRoot();
  125. return dtm_iter.getDTM(handle).getNode(handle);
  126. }
  127. /** Return a mask describing which node types are presented via the
  128. * iterator.
  129. **/
  130. public int getWhatToShow()
  131. {
  132. return dtm_iter.getWhatToShow();
  133. }
  134. /** @return the next node in the set and advance the position of the
  135. * iterator in the set.
  136. *
  137. * @throws DOMException - INVALID_STATE_ERR Raised if this method is
  138. * called after the detach method was invoked.
  139. * */
  140. public Node nextNode() throws DOMException
  141. {
  142. if(!valid)
  143. throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
  144. int handle=dtm_iter.nextNode();
  145. if (handle==DTM.NULL)
  146. return null;
  147. return dtm_iter.getDTM(handle).getNode(handle);
  148. }
  149. /** @return the next previous in the set and advance the position of the
  150. * iterator in the set.
  151. *
  152. * @throws DOMException - INVALID_STATE_ERR Raised if this method is
  153. * called after the detach method was invoked.
  154. * */
  155. public Node previousNode()
  156. {
  157. if(!valid)
  158. throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
  159. int handle=dtm_iter.previousNode();
  160. if (handle==DTM.NULL)
  161. return null;
  162. return dtm_iter.getDTM(handle).getNode(handle);
  163. }
  164. }