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: FilterExprIterator.java,v 1.5 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.xpath.internal.Expression;
  22. import com.sun.org.apache.xpath.internal.ExpressionOwner;
  23. import com.sun.org.apache.xpath.internal.XPathVisitor;
  24. import com.sun.org.apache.xpath.internal.objects.XNodeSet;
  25. public class FilterExprIterator extends BasicTestIterator
  26. {
  27. /** The contained expression. Should be non-null.
  28. * @serial */
  29. private Expression m_expr;
  30. /** The result of executing m_expr. Needs to be deep cloned on clone op. */
  31. transient private XNodeSet m_exprObj;
  32. private boolean m_mustHardReset = false;
  33. private boolean m_canDetachNodeset = true;
  34. /**
  35. * Create a ChildTestIterator object.
  36. *
  37. * @param traverser Traverser that tells how the KeyIterator is to be handled.
  38. *
  39. * @throws javax.xml.transform.TransformerException
  40. */
  41. public FilterExprIterator()
  42. {
  43. super(null);
  44. }
  45. /**
  46. * Create a ChildTestIterator object.
  47. *
  48. * @param traverser Traverser that tells how the KeyIterator is to be handled.
  49. *
  50. * @throws javax.xml.transform.TransformerException
  51. */
  52. public FilterExprIterator(Expression expr)
  53. {
  54. super(null);
  55. m_expr = expr;
  56. }
  57. /**
  58. * Initialize the context values for this expression
  59. * after it is cloned.
  60. *
  61. * @param execContext The XPath runtime context for this
  62. * transformation.
  63. */
  64. public void setRoot(int context, Object environment)
  65. {
  66. super.setRoot(context, environment);
  67. m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context,
  68. m_execContext, getPrefixResolver(),
  69. getIsTopLevel(), m_stackFrame, m_expr);
  70. }
  71. /**
  72. * Get the next node via getNextXXX. Bottlenecked for derived class override.
  73. * @return The next node on the axis, or DTM.NULL.
  74. */
  75. protected int getNextNode()
  76. {
  77. if (null != m_exprObj)
  78. {
  79. m_lastFetched = m_exprObj.nextNode();
  80. }
  81. else
  82. m_lastFetched = DTM.NULL;
  83. return m_lastFetched;
  84. }
  85. /**
  86. * Detaches the walker from the set which it iterated over, releasing
  87. * any computational resources and placing the iterator in the INVALID
  88. * state.
  89. */
  90. public void detach()
  91. {
  92. super.detach();
  93. m_exprObj.detach();
  94. m_exprObj = null;
  95. }
  96. /**
  97. * This function is used to fixup variables from QNames to stack frame
  98. * indexes at stylesheet build time.
  99. * @param vars List of QNames that correspond to variables. This list
  100. * should be searched backwards for the first qualified name that
  101. * corresponds to the variable reference qname. The position of the
  102. * QName in the vector from the start of the vector will be its position
  103. * in the stack frame (but variables above the globalsTop value will need
  104. * to be offset to the current stack frame).
  105. */
  106. public void fixupVariables(java.util.Vector vars, int globalsSize)
  107. {
  108. super.fixupVariables(vars, globalsSize);
  109. m_expr.fixupVariables(vars, globalsSize);
  110. }
  111. /**
  112. * Get the inner contained expression of this filter.
  113. */
  114. public Expression getInnerExpression()
  115. {
  116. return m_expr;
  117. }
  118. /**
  119. * Set the inner contained expression of this filter.
  120. */
  121. public void setInnerExpression(Expression expr)
  122. {
  123. expr.exprSetParent(this);
  124. m_expr = expr;
  125. }
  126. /**
  127. * Get the analysis bits for this walker, as defined in the WalkerFactory.
  128. * @return One of WalkerFactory#BIT_DESCENDANT, etc.
  129. */
  130. public int getAnalysisBits()
  131. {
  132. if (null != m_expr && m_expr instanceof PathComponent)
  133. {
  134. return ((PathComponent) m_expr).getAnalysisBits();
  135. }
  136. return WalkerFactory.BIT_FILTER;
  137. }
  138. /**
  139. * Returns true if all the nodes in the iteration well be returned in document
  140. * order.
  141. * Warning: This can only be called after setRoot has been called!
  142. *
  143. * @return true as a default.
  144. */
  145. public boolean isDocOrdered()
  146. {
  147. return m_exprObj.isDocOrdered();
  148. }
  149. class filterExprOwner implements ExpressionOwner
  150. {
  151. /**
  152. * @see ExpressionOwner#getExpression()
  153. */
  154. public Expression getExpression()
  155. {
  156. return m_expr;
  157. }
  158. /**
  159. * @see ExpressionOwner#setExpression(Expression)
  160. */
  161. public void setExpression(Expression exp)
  162. {
  163. exp.exprSetParent(FilterExprIterator.this);
  164. m_expr = exp;
  165. }
  166. }
  167. /**
  168. * This will traverse the heararchy, calling the visitor for
  169. * each member. If the called visitor method returns
  170. * false, the subtree should not be called.
  171. *
  172. * @param owner The owner of the visitor, where that path may be
  173. * rewritten if needed.
  174. * @param visitor The visitor whose appropriate method will be called.
  175. */
  176. public void callPredicateVisitors(XPathVisitor visitor)
  177. {
  178. m_expr.callVisitors(new filterExprOwner(), visitor);
  179. super.callPredicateVisitors(visitor);
  180. }
  181. /**
  182. * @see Expression#deepEquals(Expression)
  183. */
  184. public boolean deepEquals(Expression expr)
  185. {
  186. if (!super.deepEquals(expr))
  187. return false;
  188. FilterExprIterator fet = (FilterExprIterator) expr;
  189. if (!m_expr.deepEquals(fet.m_expr))
  190. return false;
  191. return true;
  192. }
  193. }