19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: WalkingIterator.java 469314 2006-10-30 23:31:59Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath.axes;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.PrefixResolver;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.Expression;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.ExpressionOwner;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.VariableStack;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathVisitor;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.Compiler;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.OpMap;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Location path iterator that uses Walkers.
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class WalkingIterator extends LocPathIterator implements ExpressionOwner
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = 9110225941815665906L;
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a WalkingIterator iterator, including creation
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of step walkers from the opcode list, and call back
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * into the Compiler to create predicate expressions.
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler The Compiler which is creating
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * this expression.
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param opPos The position of this iterator in the
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * opcode list from the compiler.
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param shouldLoadWalkers True if walkers should be
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * loaded, or false if this is a derived iterator and
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * it doesn't wish to load child walkers.
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  WalkingIterator(
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super(compiler, opPos, analysis, shouldLoadWalkers);
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int firstStepPos = OpMap.getFirstChildPos(opPos);
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (shouldLoadWalkers)
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_firstWalker = WalkerFactory.loadWalkers(this, compiler, firstStepPos, 0);
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_lastUsedWalker = m_firstWalker;
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a WalkingIterator object.
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nscontext The namespace context for this iterator,
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * should be OK if null.
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public WalkingIterator(PrefixResolver nscontext)
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super(nscontext);
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the analysis bits for this walker, as defined in the WalkerFactory.
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return One of WalkerFactory#BIT_DESCENDANT, etc.
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getAnalysisBits()
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int bits = 0;
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_firstWalker)
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      AxesWalker walker = m_firstWalker;
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (null != walker)
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int bit = walker.getAnalysisBits();
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        bits |= bit;
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        walker = walker.getNextWalker();
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return bits;
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a cloned WalkingIterator that holds the same
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * position as this iterator.
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A clone of this iterator that holds the same node position.
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws CloneNotSupportedException
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Object clone() throws CloneNotSupportedException
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    WalkingIterator clone = (WalkingIterator) super.clone();
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //    clone.m_varStackPos = this.m_varStackPos;
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //    clone.m_varStackContext = this.m_varStackContext;
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_firstWalker)
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      clone.m_firstWalker = m_firstWalker.cloneDeep(clone, null);
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return clone;
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Reset the iterator.
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void reset()
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super.reset();
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_firstWalker)
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_lastUsedWalker = m_firstWalker;
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_firstWalker.setRoot(m_context);
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initialize the context values for this expression
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * after it is cloned.
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param context The XPath runtime context for this
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * transformation.
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setRoot(int context, Object environment)
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super.setRoot(context, environment);
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_firstWalker)
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_firstWalker.setRoot(context);
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_lastUsedWalker = m_firstWalker;
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  Returns the next node in the set and advances the position of the
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * iterator in the set. After a NodeIterator is created, the first call
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to nextNode() returns the first node in the set.
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return  The next <code>Node</code> in the set being iterated over, or
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   <code>null</code> if there are no more members in that set.
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int nextNode()
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(m_foundLast)
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return DTM.NULL;
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // If the variable stack position is not -1, we'll have to
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // set our position in the variable stack, so our variable access
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // will be correct.  Iterators that are at the top level of the
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // expression need to reset the variable stack, while iterators
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // in predicates do not need to, and should not, since their execution
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // may be much later than top-level iterators.
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // m_varStackPos is set in setRoot, which is called
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // from the execute method.
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (-1 == m_stackFrame)
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return returnNextNode(m_firstWalker.nextNode());
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      VariableStack vars = m_execContext.getVarStack();
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // These three statements need to be combined into one operation.
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int savedStart = vars.getStackFrame();
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      vars.setStackFrame(m_stackFrame);
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int n = returnNextNode(m_firstWalker.nextNode());
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // These two statements need to be combined into one operation.
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      vars.setStackFrame(savedStart);
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return n;
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the head of the walker list.
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The head of the walker list, or null
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if this iterator does not implement walkers.
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage advanced
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final AxesWalker getFirstWalker()
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_firstWalker;
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the head of the walker list.
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param walker Should be a valid AxesWalker.
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage advanced
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void setFirstWalker(AxesWalker walker)
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_firstWalker = walker;
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the last used walker.
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param walker The last used walker, or null.
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage advanced
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void setLastUsedWalker(AxesWalker walker)
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_lastUsedWalker = walker;
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the last used walker.
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The last used walker, or null.
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage advanced
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final AxesWalker getLastUsedWalker()
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_lastUsedWalker;
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  Detaches the iterator from the set which it iterated over, releasing
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * any computational resources and placing the iterator in the INVALID
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * state. After<code>detach</code> has been invoked, calls to
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <code>nextNode</code> or<code>previousNode</code> will raise the
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * exception INVALID_STATE_ERR.
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void detach()
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_allowDetach)
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	AxesWalker walker = m_firstWalker;
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    while (null != walker)
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      walker.detach();
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      walker = walker.getNextWalker();
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    m_lastUsedWalker = null;
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    // Always call the superclass detach last!
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    super.detach();
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This function is used to fixup variables from QNames to stack frame
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * indexes at stylesheet build time.
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param vars List of QNames that correspond to variables.  This list
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * should be searched backwards for the first qualified name that
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * corresponds to the variable reference qname.  The position of the
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * QName in the vector from the start of the vector will be its position
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in the stack frame (but variables above the globalsTop value will need
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to be offset to the current stack frame).
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void fixupVariables(java.util.Vector vars, int globalsSize)
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_predicateIndex = -1;
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    AxesWalker walker = m_firstWalker;
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (null != walker)
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      walker.fixupVariables(vars, globalsSize);
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      walker = walker.getNextWalker();
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 	if(visitor.visitLocationPath(owner, this))
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 	{
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 		if(null != m_firstWalker)
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 		{
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 			m_firstWalker.callVisitors(this, visitor);
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 		}
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	 	}
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The last used step walker in the walker list.
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected AxesWalker m_lastUsedWalker;
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The head of the step walker list.
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial */
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected AxesWalker m_firstWalker;
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see ExpressionOwner#getExpression()
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Expression getExpression()
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_firstWalker;
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see ExpressionOwner#setExpression(Expression)
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setExpression(Expression exp)
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	exp.exprSetParent(this);
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	m_firstWalker = (AxesWalker)exp;
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see Expression#deepEquals(Expression)
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean deepEquals(Expression expr)
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (!super.deepEquals(expr))
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return false;
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      AxesWalker walker1 = m_firstWalker;
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      AxesWalker walker2 = ((WalkingIterator)expr).m_firstWalker;
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while ((null != walker1) && (null != walker2))
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(!walker1.deepEquals(walker2))
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        	return false;
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        walker1 = walker1.getNextWalker();
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        walker2 = walker2.getNextWalker();
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if((null != walker1) || (null != walker2))
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	return false;
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
364