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: DTMAxisIterNodeList.java,v 1.3 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.DTMAxisIterator;
  22. import com.sun.org.apache.xml.internal.utils.IntVector;
  23. import org.w3c.dom.Node;
  24. /**
  25. * <code>DTMAxisNodeList</code> gives us an implementation of the DOM's
  26. * NodeList interface wrapped around a DTM Iterator. The author
  27. * considers this something of an abominations, since NodeList was not
  28. * intended to be a general purpose "list of nodes" API and is
  29. * generally considered by the DOM WG to have be a mistake... but I'm
  30. * told that some of the XPath/XSLT folks say they must have this
  31. * solution.
  32. *
  33. * Please note that this is not necessarily equivlaent to a DOM
  34. * NodeList operating over the same document. In particular:
  35. * <ul>
  36. *
  37. * <li>If there are several Text nodes in logical succession (ie,
  38. * across CDATASection and EntityReference boundaries), we will return
  39. * only the first; the caller is responsible for stepping through
  40. * them.
  41. * (%REVIEW% Provide a convenience routine here to assist, pending
  42. * proposed DOM Level 3 getAdjacentText() operation?) </li>
  43. *
  44. * <li>Since the whole XPath/XSLT architecture assumes that the source
  45. * document is not altered while we're working with it, we do not
  46. * promise to implement the DOM NodeList's "live view" response to
  47. * document mutation. </li>
  48. *
  49. * </ul>
  50. *
  51. * <p>State: In progress!!</p>
  52. * */
  53. public class DTMAxisIterNodeList extends DTMNodeListBase {
  54. private DTM m_dtm;
  55. private DTMAxisIterator m_iter;
  56. private IntVector m_cachedNodes;
  57. private int m_last = -1;
  58. //================================================================
  59. // Methods unique to this class
  60. private DTMAxisIterNodeList() {
  61. }
  62. /**
  63. * Public constructor: Wrap a DTMNodeList around an existing
  64. * and preconfigured DTMAxisIterator
  65. */
  66. public DTMAxisIterNodeList(DTM dtm, DTMAxisIterator dtmAxisIterator) {
  67. if (dtmAxisIterator == null) {
  68. m_last = 0;
  69. } else {
  70. m_cachedNodes = new IntVector();
  71. m_dtm = dtm;
  72. }
  73. m_iter = dtmAxisIterator;
  74. }
  75. /**
  76. * Access the wrapped DTMIterator. I'm not sure whether anyone will
  77. * need this or not, but let's write it and think about it.
  78. *
  79. */
  80. public DTMAxisIterator getDTMAxisIterator() {
  81. return m_iter;
  82. }
  83. //================================================================
  84. // org.w3c.dom.NodeList API follows
  85. /**
  86. * Returns the <code>index</code>th item in the collection. If
  87. * <code>index</code> is greater than or equal to the number of nodes in
  88. * the list, this returns <code>null</code>.
  89. * @param indexIndex into the collection.
  90. * @return The node at the <code>index</code>th position in the
  91. * <code>NodeList</code>, or <code>null</code> if that is not a valid
  92. * index.
  93. */
  94. public Node item(int index) {
  95. if (m_iter != null) {
  96. int node;
  97. int count = m_cachedNodes.size();
  98. if (count > index) {
  99. node = m_cachedNodes.elementAt(index);
  100. return m_dtm.getNode(node);
  101. } else if (m_last == -1) {
  102. while (((node = m_iter.next()) != DTMAxisIterator.END)
  103. && count <= index) {
  104. m_cachedNodes.addElement(node);
  105. count++;
  106. }
  107. if (node == DTMAxisIterator.END) {
  108. m_last = count;
  109. } else {
  110. return m_dtm.getNode(node);
  111. }
  112. }
  113. }
  114. return null;
  115. }
  116. /**
  117. * The number of nodes in the list. The range of valid child node indices
  118. * is 0 to <code>length-1</code> inclusive.
  119. */
  120. public int getLength() {
  121. if (m_last == -1) {
  122. int node;
  123. while ((node = m_iter.next()) != DTMAxisIterator.END) {
  124. m_cachedNodes.addElement(node);
  125. }
  126. m_last = m_cachedNodes.size();
  127. }
  128. return m_last;
  129. }
  130. }