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