1e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo/*
234ee09551764b045fdc02df754157473125edf60Kevin Tang * Licensed to the Apache Software Foundation (ASF) under one
334ee09551764b045fdc02df754157473125edf60Kevin Tang * or more contributor license agreements. See the NOTICE file
434ee09551764b045fdc02df754157473125edf60Kevin Tang * distributed with this work for additional information
534ee09551764b045fdc02df754157473125edf60Kevin Tang * regarding copyright ownership. The ASF licenses this file
634ee09551764b045fdc02df754157473125edf60Kevin Tang * to you under the Apache License, Version 2.0 (the  "License");
734ee09551764b045fdc02df754157473125edf60Kevin Tang * you may not use this file except in compliance with the License.
834ee09551764b045fdc02df754157473125edf60Kevin Tang * You may obtain a copy of the License at
934ee09551764b045fdc02df754157473125edf60Kevin Tang *
1034ee09551764b045fdc02df754157473125edf60Kevin Tang *     http://www.apache.org/licenses/LICENSE-2.0
1134ee09551764b045fdc02df754157473125edf60Kevin Tang *
12e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * Unless required by applicable law or agreed to in writing, software
1334ee09551764b045fdc02df754157473125edf60Kevin Tang * distributed under the License is distributed on an "AS IS" BASIS,
1434ee09551764b045fdc02df754157473125edf60Kevin Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1534ee09551764b045fdc02df754157473125edf60Kevin Tang * See the License for the specific language governing permissions and
1634ee09551764b045fdc02df754157473125edf60Kevin Tang * limitations under the License.
1734ee09551764b045fdc02df754157473125edf60Kevin Tang */
1834ee09551764b045fdc02df754157473125edf60Kevin Tang/*
1934ee09551764b045fdc02df754157473125edf60Kevin Tang * $Id: FilterExprIterator.java 468655 2006-10-28 07:12:06Z minchau $
2034ee09551764b045fdc02df754157473125edf60Kevin Tang */
2134ee09551764b045fdc02df754157473125edf60Kevin Tangpackage org.apache.xpath.axes;
2234ee09551764b045fdc02df754157473125edf60Kevin Tang
2334ee09551764b045fdc02df754157473125edf60Kevin Tangimport org.apache.xml.dtm.DTM;
2434ee09551764b045fdc02df754157473125edf60Kevin Tangimport org.apache.xpath.Expression;
2534ee09551764b045fdc02df754157473125edf60Kevin Tangimport org.apache.xpath.ExpressionOwner;
2634ee09551764b045fdc02df754157473125edf60Kevin Tangimport org.apache.xpath.XPathVisitor;
2734ee09551764b045fdc02df754157473125edf60Kevin Tangimport org.apache.xpath.objects.XNodeSet;
2834ee09551764b045fdc02df754157473125edf60Kevin Tang
2934ee09551764b045fdc02df754157473125edf60Kevin Tangpublic class FilterExprIterator extends BasicTestIterator
3034ee09551764b045fdc02df754157473125edf60Kevin Tang{
3134ee09551764b045fdc02df754157473125edf60Kevin Tang    static final long serialVersionUID = 2552176105165737614L;
3234ee09551764b045fdc02df754157473125edf60Kevin Tang  /** The contained expression. Should be non-null.
3334ee09551764b045fdc02df754157473125edf60Kevin Tang   *  @serial   */
34e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  private Expression m_expr;
3534ee09551764b045fdc02df754157473125edf60Kevin Tang
36e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */
37e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  transient private XNodeSet m_exprObj;
38e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
39e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  private boolean m_mustHardReset = false;
40e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  private boolean m_canDetachNodeset = true;
41e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
42e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /**
43e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * Create a FilterExprIterator object.
44e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   *
45e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   */
46e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  public FilterExprIterator()
47e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
48e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    super(null);
49e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  }
50e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
51e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /**
52e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * Create a FilterExprIterator object.
53e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   *
54e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   */
55e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  public FilterExprIterator(Expression expr)
56e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
57e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    super(null);
58e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    m_expr = expr;
59e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  }
60e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
61e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /**
62e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * Initialize the context values for this expression
63e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * after it is cloned.
64e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   *
65e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * @param context The XPath runtime context for this
66e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * transformation.
67e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   */
68e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  public void setRoot(int context, Object environment)
69e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
70e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  	super.setRoot(context, environment);
71e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
72e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  	m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context,
73e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  	                  m_execContext, getPrefixResolver(),
74e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  	                  getIsTopLevel(), m_stackFrame, m_expr);
75e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   }
76e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
77e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
78e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /**
79e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * Get the next node via getNextXXX.  Bottlenecked for derived class override.
80e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * @return The next node on the axis, or DTM.NULL.
81e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   */
82e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  protected int getNextNode()
83e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
8434ee09551764b045fdc02df754157473125edf60Kevin Tang    if (null != m_exprObj)
85bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
86bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo      m_lastFetched = m_exprObj.nextNode();
87bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
88bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    else
89bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo      m_lastFetched = DTM.NULL;
90bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
91bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    return m_lastFetched;
92bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  }
93bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
94bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  /**
95bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * Detaches the walker from the set which it iterated over, releasing
96bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * any computational resources and placing the iterator in the INVALID
97bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * state.
98bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   */
99bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  public void detach()
100bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  {
101bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  	super.detach();
102bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  	m_exprObj.detach();
103bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  	m_exprObj = null;
10434ee09551764b045fdc02df754157473125edf60Kevin Tang  }
10534ee09551764b045fdc02df754157473125edf60Kevin Tang
10634ee09551764b045fdc02df754157473125edf60Kevin Tang  /**
10734ee09551764b045fdc02df754157473125edf60Kevin Tang   * This function is used to fixup variables from QNames to stack frame
10834ee09551764b045fdc02df754157473125edf60Kevin Tang   * indexes at stylesheet build time.
10934ee09551764b045fdc02df754157473125edf60Kevin Tang   * @param vars List of QNames that correspond to variables.  This list
11034ee09551764b045fdc02df754157473125edf60Kevin Tang   * should be searched backwards for the first qualified name that
11134ee09551764b045fdc02df754157473125edf60Kevin Tang   * corresponds to the variable reference qname.  The position of the
11234ee09551764b045fdc02df754157473125edf60Kevin Tang   * QName in the vector from the start of the vector will be its position
11334ee09551764b045fdc02df754157473125edf60Kevin Tang   * in the stack frame (but variables above the globalsTop value will need
11434ee09551764b045fdc02df754157473125edf60Kevin Tang   * to be offset to the current stack frame).
11534ee09551764b045fdc02df754157473125edf60Kevin Tang   */
11634ee09551764b045fdc02df754157473125edf60Kevin Tang  public void fixupVariables(java.util.Vector vars, int globalsSize)
11734ee09551764b045fdc02df754157473125edf60Kevin Tang  {
11834ee09551764b045fdc02df754157473125edf60Kevin Tang    super.fixupVariables(vars, globalsSize);
11934ee09551764b045fdc02df754157473125edf60Kevin Tang    m_expr.fixupVariables(vars, globalsSize);
12034ee09551764b045fdc02df754157473125edf60Kevin Tang  }
121e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
12234ee09551764b045fdc02df754157473125edf60Kevin Tang  /**
123e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * Get the inner contained expression of this filter.
124e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   */
125bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  public Expression getInnerExpression()
126e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
127e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return m_expr;
128e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  }
129e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
130e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /**
131e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * Set the inner contained expression of this filter.
132e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   */
133e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  public void setInnerExpression(Expression expr)
134e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
135e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    expr.exprSetParent(this);
136bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    m_expr = expr;
137e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  }
13834ee09551764b045fdc02df754157473125edf60Kevin Tang
13934ee09551764b045fdc02df754157473125edf60Kevin Tang  /**
14034ee09551764b045fdc02df754157473125edf60Kevin Tang   * Get the analysis bits for this walker, as defined in the WalkerFactory.
14134ee09551764b045fdc02df754157473125edf60Kevin Tang   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
14234ee09551764b045fdc02df754157473125edf60Kevin Tang   */
14334ee09551764b045fdc02df754157473125edf60Kevin Tang  public int getAnalysisBits()
14434ee09551764b045fdc02df754157473125edf60Kevin Tang  {
14534ee09551764b045fdc02df754157473125edf60Kevin Tang    if (null != m_expr && m_expr instanceof PathComponent)
14634ee09551764b045fdc02df754157473125edf60Kevin Tang    {
14734ee09551764b045fdc02df754157473125edf60Kevin Tang      return ((PathComponent) m_expr).getAnalysisBits();
14834ee09551764b045fdc02df754157473125edf60Kevin Tang    }
14934ee09551764b045fdc02df754157473125edf60Kevin Tang    return WalkerFactory.BIT_FILTER;
150bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  }
15134ee09551764b045fdc02df754157473125edf60Kevin Tang
15234ee09551764b045fdc02df754157473125edf60Kevin Tang  /**
15334ee09551764b045fdc02df754157473125edf60Kevin Tang   * Returns true if all the nodes in the iteration well be returned in document
15434ee09551764b045fdc02df754157473125edf60Kevin Tang   * order.
15534ee09551764b045fdc02df754157473125edf60Kevin Tang   * Warning: This can only be called after setRoot has been called!
15634ee09551764b045fdc02df754157473125edf60Kevin Tang   *
15734ee09551764b045fdc02df754157473125edf60Kevin Tang   * @return true as a default.
15834ee09551764b045fdc02df754157473125edf60Kevin Tang   */
159bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  public boolean isDocOrdered()
160e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
161e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return m_exprObj.isDocOrdered();
162bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  }
16334ee09551764b045fdc02df754157473125edf60Kevin Tang
16434ee09551764b045fdc02df754157473125edf60Kevin Tang  class filterExprOwner implements ExpressionOwner
165e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  {
166e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    /**
167e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    * @see ExpressionOwner#getExpression()
168e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    */
169e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    public Expression getExpression()
170e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
171e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo      return m_expr;
172e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
173e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
174e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    /**
175bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo     * @see ExpressionOwner#setExpression(Expression)
176e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo     */
177e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    public void setExpression(Expression exp)
178e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
179e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo      exp.exprSetParent(FilterExprIterator.this);
180e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo      m_expr = exp;
181e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
182e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
183bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  }
184e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
185e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo  /**
186bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * This will traverse the heararchy, calling the visitor for
187e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo   * each member.  If the called visitor method returns
188bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * false, the subtree should not be called.
189bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   *
190bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * @param visitor The visitor whose appropriate method will be called.
191bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   */
192bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  public void callPredicateVisitors(XPathVisitor visitor)
193bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  {
194bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    m_expr.callVisitors(new filterExprOwner(), visitor);
195e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
196bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    super.callPredicateVisitors(visitor);
197bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  }
198bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
199bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  /**
200bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   * @see Expression#deepEquals(Expression)
201bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   */
202bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  public boolean deepEquals(Expression expr)
203bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  {
204bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (!super.deepEquals(expr))
205bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo      return false;
206bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
207bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    FilterExprIterator fet = (FilterExprIterator) expr;
208bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (!m_expr.deepEquals(fet.m_expr))
209bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo      return false;
210bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
211bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    return true;
212bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo  }
213e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
214}
215