1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the  "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18/*
19 * $Id: FilterExprIterator.java 468655 2006-10-28 07:12:06Z minchau $
20 */
21package org.apache.xpath.axes;
22
23import org.apache.xml.dtm.DTM;
24import org.apache.xpath.Expression;
25import org.apache.xpath.ExpressionOwner;
26import org.apache.xpath.XPathVisitor;
27import org.apache.xpath.objects.XNodeSet;
28
29public class FilterExprIterator extends BasicTestIterator
30{
31    static final long serialVersionUID = 2552176105165737614L;
32  /** The contained expression. Should be non-null.
33   *  @serial   */
34  private Expression m_expr;
35
36  /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */
37  transient private XNodeSet m_exprObj;
38
39  private boolean m_mustHardReset = false;
40  private boolean m_canDetachNodeset = true;
41
42  /**
43   * Create a FilterExprIterator object.
44   *
45   */
46  public FilterExprIterator()
47  {
48    super(null);
49  }
50
51  /**
52   * Create a FilterExprIterator object.
53   *
54   */
55  public FilterExprIterator(Expression expr)
56  {
57    super(null);
58    m_expr = expr;
59  }
60
61  /**
62   * Initialize the context values for this expression
63   * after it is cloned.
64   *
65   * @param context The XPath runtime context for this
66   * transformation.
67   */
68  public void setRoot(int context, Object environment)
69  {
70  	super.setRoot(context, environment);
71
72  	m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context,
73  	                  m_execContext, getPrefixResolver(),
74  	                  getIsTopLevel(), m_stackFrame, m_expr);
75   }
76
77
78  /**
79   * Get the next node via getNextXXX.  Bottlenecked for derived class override.
80   * @return The next node on the axis, or DTM.NULL.
81   */
82  protected int getNextNode()
83  {
84    if (null != m_exprObj)
85    {
86      m_lastFetched = m_exprObj.nextNode();
87    }
88    else
89      m_lastFetched = DTM.NULL;
90
91    return m_lastFetched;
92  }
93
94  /**
95   * Detaches the walker from the set which it iterated over, releasing
96   * any computational resources and placing the iterator in the INVALID
97   * state.
98   */
99  public void detach()
100  {
101  	super.detach();
102  	m_exprObj.detach();
103  	m_exprObj = null;
104  }
105
106  /**
107   * This function is used to fixup variables from QNames to stack frame
108   * indexes at stylesheet build time.
109   * @param vars List of QNames that correspond to variables.  This list
110   * should be searched backwards for the first qualified name that
111   * corresponds to the variable reference qname.  The position of the
112   * QName in the vector from the start of the vector will be its position
113   * in the stack frame (but variables above the globalsTop value will need
114   * to be offset to the current stack frame).
115   */
116  public void fixupVariables(java.util.Vector vars, int globalsSize)
117  {
118    super.fixupVariables(vars, globalsSize);
119    m_expr.fixupVariables(vars, globalsSize);
120  }
121
122  /**
123   * Get the inner contained expression of this filter.
124   */
125  public Expression getInnerExpression()
126  {
127    return m_expr;
128  }
129
130  /**
131   * Set the inner contained expression of this filter.
132   */
133  public void setInnerExpression(Expression expr)
134  {
135    expr.exprSetParent(this);
136    m_expr = expr;
137  }
138
139  /**
140   * Get the analysis bits for this walker, as defined in the WalkerFactory.
141   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
142   */
143  public int getAnalysisBits()
144  {
145    if (null != m_expr && m_expr instanceof PathComponent)
146    {
147      return ((PathComponent) m_expr).getAnalysisBits();
148    }
149    return WalkerFactory.BIT_FILTER;
150  }
151
152  /**
153   * Returns true if all the nodes in the iteration well be returned in document
154   * order.
155   * Warning: This can only be called after setRoot has been called!
156   *
157   * @return true as a default.
158   */
159  public boolean isDocOrdered()
160  {
161    return m_exprObj.isDocOrdered();
162  }
163
164  class filterExprOwner implements ExpressionOwner
165  {
166    /**
167    * @see ExpressionOwner#getExpression()
168    */
169    public Expression getExpression()
170    {
171      return m_expr;
172    }
173
174    /**
175     * @see ExpressionOwner#setExpression(Expression)
176     */
177    public void setExpression(Expression exp)
178    {
179      exp.exprSetParent(FilterExprIterator.this);
180      m_expr = exp;
181    }
182
183  }
184
185  /**
186   * This will traverse the heararchy, calling the visitor for
187   * each member.  If the called visitor method returns
188   * false, the subtree should not be called.
189   *
190   * @param visitor The visitor whose appropriate method will be called.
191   */
192  public void callPredicateVisitors(XPathVisitor visitor)
193  {
194    m_expr.callVisitors(new filterExprOwner(), visitor);
195
196    super.callPredicateVisitors(visitor);
197  }
198
199  /**
200   * @see Expression#deepEquals(Expression)
201   */
202  public boolean deepEquals(Expression expr)
203  {
204    if (!super.deepEquals(expr))
205      return false;
206
207    FilterExprIterator fet = (FilterExprIterator) expr;
208    if (!m_expr.deepEquals(fet.m_expr))
209      return false;
210
211    return true;
212  }
213
214}
215