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: BasicTestIterator.java,v 1.6 2004/02/17 04:32:08 minchau Exp $
  18. */
  19. package com.sun.org.apache.xpath.internal.axes;
  20. import com.sun.org.apache.xml.internal.dtm.DTM;
  21. import com.sun.org.apache.xml.internal.dtm.DTMFilter;
  22. import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  23. import com.sun.org.apache.xml.internal.utils.PrefixResolver;
  24. import com.sun.org.apache.xpath.internal.compiler.Compiler;
  25. /**
  26. * Base for iterators that handle predicates. Does the basic next
  27. * node logic, so all the derived iterator has to do is get the
  28. * next node.
  29. */
  30. public abstract class BasicTestIterator extends LocPathIterator
  31. {
  32. /**
  33. * Create a LocPathIterator object.
  34. *
  35. * @param nscontext The namespace context for this iterator,
  36. * should be OK if null.
  37. */
  38. protected BasicTestIterator()
  39. {
  40. }
  41. /**
  42. * Create a LocPathIterator object.
  43. *
  44. * @param nscontext The namespace context for this iterator,
  45. * should be OK if null.
  46. */
  47. protected BasicTestIterator(PrefixResolver nscontext)
  48. {
  49. super(nscontext);
  50. }
  51. /**
  52. * Create a LocPathIterator object, including creation
  53. * of step walkers from the opcode list, and call back
  54. * into the Compiler to create predicate expressions.
  55. *
  56. * @param compiler The Compiler which is creating
  57. * this expression.
  58. * @param opPos The position of this iterator in the
  59. * opcode list from the compiler.
  60. *
  61. * @throws javax.xml.transform.TransformerException
  62. */
  63. protected BasicTestIterator(Compiler compiler, int opPos, int analysis)
  64. throws javax.xml.transform.TransformerException
  65. {
  66. super(compiler, opPos, analysis, false);
  67. int firstStepPos = compiler.getFirstChildPos(opPos);
  68. int whatToShow = compiler.getWhatToShow(firstStepPos);
  69. if ((0 == (whatToShow
  70. & (DTMFilter.SHOW_ATTRIBUTE
  71. | DTMFilter.SHOW_NAMESPACE
  72. | DTMFilter.SHOW_ELEMENT
  73. | DTMFilter.SHOW_PROCESSING_INSTRUCTION)))
  74. || (whatToShow == DTMFilter.SHOW_ALL))
  75. initNodeTest(whatToShow);
  76. else
  77. {
  78. initNodeTest(whatToShow, compiler.getStepNS(firstStepPos),
  79. compiler.getStepLocalName(firstStepPos));
  80. }
  81. initPredicateInfo(compiler, firstStepPos);
  82. }
  83. /**
  84. * Create a LocPathIterator object, including creation
  85. * of step walkers from the opcode list, and call back
  86. * into the Compiler to create predicate expressions.
  87. *
  88. * @param compiler The Compiler which is creating
  89. * this expression.
  90. * @param opPos The position of this iterator in the
  91. * opcode list from the compiler.
  92. * @param shouldLoadWalkers True if walkers should be
  93. * loaded, or false if this is a derived iterator and
  94. * it doesn't wish to load child walkers.
  95. *
  96. * @throws javax.xml.transform.TransformerException
  97. */
  98. protected BasicTestIterator(
  99. Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
  100. throws javax.xml.transform.TransformerException
  101. {
  102. super(compiler, opPos, analysis, shouldLoadWalkers);
  103. }
  104. /**
  105. * Get the next node via getNextXXX. Bottlenecked for derived class override.
  106. * @return The next node on the axis, or DTM.NULL.
  107. */
  108. protected abstract int getNextNode();
  109. /**
  110. * Returns the next node in the set and advances the position of the
  111. * iterator in the set. After a NodeIterator is created, the first call
  112. * to nextNode() returns the first node in the set.
  113. *
  114. * @return The next <code>Node</code> in the set being iterated over, or
  115. * <code>null</code> if there are no more members in that set.
  116. */
  117. public int nextNode()
  118. {
  119. if(m_foundLast)
  120. {
  121. m_lastFetched = DTM.NULL;
  122. return DTM.NULL;
  123. }
  124. if(DTM.NULL == m_lastFetched)
  125. {
  126. resetProximityPositions();
  127. }
  128. int next;
  129. com.sun.org.apache.xpath.internal.VariableStack vars;
  130. int savedStart;
  131. if (-1 != m_stackFrame)
  132. {
  133. vars = m_execContext.getVarStack();
  134. // These three statements need to be combined into one operation.
  135. savedStart = vars.getStackFrame();
  136. vars.setStackFrame(m_stackFrame);
  137. }
  138. else
  139. {
  140. // Yuck. Just to shut up the compiler!
  141. vars = null;
  142. savedStart = 0;
  143. }
  144. try
  145. {
  146. do
  147. {
  148. next = getNextNode();
  149. if (DTM.NULL != next)
  150. {
  151. if(DTMIterator.FILTER_ACCEPT == acceptNode(next))
  152. break;
  153. else
  154. continue;
  155. }
  156. else
  157. break;
  158. }
  159. while (next != DTM.NULL);
  160. if (DTM.NULL != next)
  161. {
  162. m_pos++;
  163. return next;
  164. }
  165. else
  166. {
  167. m_foundLast = true;
  168. return DTM.NULL;
  169. }
  170. }
  171. finally
  172. {
  173. if (-1 != m_stackFrame)
  174. {
  175. // These two statements need to be combined into one operation.
  176. vars.setStackFrame(savedStart);
  177. }
  178. }
  179. }
  180. /**
  181. * Get a cloned Iterator that is reset to the beginning
  182. * of the query.
  183. *
  184. * @return A cloned NodeIterator set of the start of the query.
  185. *
  186. * @throws CloneNotSupportedException
  187. */
  188. public DTMIterator cloneWithReset() throws CloneNotSupportedException
  189. {
  190. ChildTestIterator clone = (ChildTestIterator) super.cloneWithReset();
  191. clone.resetProximityPositions();
  192. return clone;
  193. }
  194. }