sboag       01/05/26 19:28:53

  Modified:    java/src/org/apache/xalan/transformer Tag: DTM_EXP
                        KeyIterator.java
               java/src/org/apache/xml/dtm/ref Tag: DTM_EXP
                        DTMDefaultBaseIterators.java
                        DTMDefaultBaseTraversers.java
               java/src/org/apache/xpath/axes Tag: DTM_EXP
                        AttributeIterator.java AxesWalker.java
                        ChildIterator.java ChildTestIterator.java
                        ChildWalkerMultiStep.java DescendantIterator.java
                        FilterExprWalker.java LocPathIterator.java
                        MatchPatternIterator.java PredicatedNodeTest.java
                        ReverseAxesWalker.java UnionPathIterator.java
                        WalkerFactory.java
               java/src/org/apache/xpath/functions Tag: DTM_EXP
                        FuncLocalPart.java
  Added:       java/src/org/apache/xpath/axes Tag: DTM_EXP
                        OneStepIterator.java OneStepIteratorForward.java
                        SelfIteratorNoPredicate.java WalkingIterator.java
  Log:
  Added onestep iterators which use DTM traversers or iterators, and are
  applicable to any one-step path.  Added self iterator for "." (can't
  believe I didn't do this before).  Moved walker portion of 
LocationPathIterator
  to WalkingIterator, and made LocationPathIterator abstract.  Removed
  the waiting logic from AxisWalker (thank god and good riddence).
  Added many functions to WalkerFactory to determine the structure
  of the LocationPath, and added much logic to choose the right
  iterator, including looking into predicates to determine if they could
  have a proximity predicate or function, and, if not, use a descendant
  iterator if everything else is right.  Also, detirmine if path steps
  can criss-cross, and, if so, use the MatchIterator (this let me
  get rid of waiting walkers).  Also, made many fixes to DTM traversers
  and iterators.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.9.2.3   +2 -7      
xml-xalan/java/src/org/apache/xalan/transformer/KeyIterator.java
  
  Index: KeyIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/KeyIterator.java,v
  retrieving revision 1.9.2.2
  retrieving revision 1.9.2.3
  diff -u -r1.9.2.2 -r1.9.2.3
  --- KeyIterator.java  2001/05/18 07:16:24     1.9.2.2
  +++ KeyIterator.java  2001/05/27 02:28:45     1.9.2.3
  @@ -58,7 +58,7 @@
   
   import java.util.Vector;
   
  -import org.apache.xpath.axes.LocPathIterator;
  +import org.apache.xpath.axes.WalkingIterator;
   import org.apache.xml.utils.PrefixResolver;
   import org.apache.xml.utils.XMLString;
   import org.apache.xml.utils.QName;
  @@ -68,11 +68,6 @@
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.XPath;
   
  -//import org.w3c.dom.Node;
  -//import org.w3c.dom.DOMException;
  -//import org.w3c.dom.NamedNodeMap;
  -//import org.w3c.dom.traversal.NodeFilter;
  -//import org.w3c.dom.traversal.NodeIterator;
   import org.apache.xml.dtm.DTM;
   
   import javax.xml.transform.TransformerException;
  @@ -84,7 +79,7 @@
    * source tree and finds all the nodes that match
    * a given key name and match pattern.
    */
  -public class KeyIterator extends LocPathIterator
  +public class KeyIterator extends WalkingIterator
   {
     
     /** The key table this iterator is associated to.
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +245 -61   
xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBaseIterators.java
  
  Index: DTMDefaultBaseIterators.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBaseIterators.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- DTMDefaultBaseIterators.java      2001/05/23 02:56:57     1.1.2.1
  +++ DTMDefaultBaseIterators.java      2001/05/27 02:28:46     1.1.2.2
  @@ -151,6 +151,12 @@
         case Axis.PRECEDINGSIBLING :
           iterator = new TypedPrecedingSiblingIterator(type);
           break;
  +      case Axis.NAMESPACE :
  +        iterator = new TypedNamespaceIterator(type);
  +        break;
  +      case Axis.ROOT :
  +        iterator = new TypedRootIterator(type);
  +        break;
         default :
           throw new DTMException("Error: typed iterator for axis "
                                  + Axis.names[axis] + "not implemented");
  @@ -210,8 +216,11 @@
         iterator = new PrecedingSiblingIterator();
         break;
       case Axis.NAMESPACE :
  -
  -    // return(new N()); %TBD%
  +      iterator = new NamespaceIterator();
  +      break;
  +    case Axis.ROOT :
  +      iterator = new RootIterator();
  +      break;
       default :
         throw new DTMException("Error: iterator for axis '" + Axis.names[axis]
                                + "' not implemented");
  @@ -529,7 +538,205 @@
         return END;
       }
     }  // end of TypedChildrenIterator
  +  
  +  /**
  +   * Iterator that returns the namespace nodes as defined by the XPath data 
model 
  +   * for a given node.
  +   */
  +  private class NamespaceIterator
  +          extends InternalAxisIteratorBase
  +  {
  +
  +    /**
  +     * Constructor NamespaceAttributeIterator
  +     */
  +    public NamespaceIterator()
  +    {
  +
  +      super();
  +    }
  +
  +    /**
  +     * Set start to END should 'close' the iterator,
  +     * i.e. subsequent call to next() should return END.
  +     *
  +     * @param node Sets the root of the iteration.
  +     *
  +     * @return A DTMAxisIterator set to the start of the iteration.
  +     */
  +    public DTMAxisIterator setStartNode(int node)
  +    {
  +
  +      if (_isRestartable)
  +      {
  +        _startNode = node;
  +        _currentNode = getFirstNamespaceNode(node, true);
  +
  +        return resetPosition();
  +      }
  +
  +      return this;
  +    }
  +
  +    /**
  +     * Get the next node in the iteration.
  +     *
  +     * @return The next node handle in the iteration, or END.
  +     */
  +    public int next()
  +    {
  +
  +      int node = _currentNode;
  +
  +      if (DTM.NULL != node)
  +        _currentNode = getNextNamespaceNode(_startNode, node, true);
  +
  +      return returnNode(node);
  +    }
  +  }  // end of NamespaceIterator
  +  
  +  /**
  +   * Iterator that returns the namespace nodes as defined by the XPath data 
model 
  +   * for a given node, filtered by extended type ID.
  +   */
  +  private class TypedNamespaceIterator extends NamespaceIterator
  +  {
  +
  +    /** The extended type ID that was requested. */
  +    private final int _nodeType;
  +
  +    /**
  +     * Constructor TypedChildrenIterator
  +     *
  +     *
  +     * @param nodeType The extended type ID being requested.
  +     */
  +    public TypedNamespaceIterator(int nodeType)
  +    {
  +      super();
  +      _nodeType = nodeType;
  +    }
  +
  +    /**
  +     * Get the next node in the iteration.
  +     *
  +     * @return The next node handle in the iteration, or END.
  +     */
  +    public int next()
  +    {
  +
  +      for (int node = super.next(); node != END; node = super.next())
  +      {
  +        if (getExpandedTypeID(node) == _nodeType)
  +        {
  +          _currentNode = node;
  +
  +          return returnNode(node);
  +        }
  +      }
  +
  +      return END;
  +    }
  +  }  // end of TypedNamespaceIterator
  +  
  +  /**
  +   * Iterator that returns the the root node as defined by the XPath data 
model 
  +   * for a given node.
  +   */
  +  private class RootIterator
  +          extends InternalAxisIteratorBase
  +  {
  +
  +    /**
  +     * Constructor RootIterator
  +     */
  +    public RootIterator()
  +    {
  +
  +      super();
  +    }
  +
  +    /**
  +     * Set start to END should 'close' the iterator,
  +     * i.e. subsequent call to next() should return END.
  +     *
  +     * @param node Sets the root of the iteration.
  +     *
  +     * @return A DTMAxisIterator set to the start of the iteration.
  +     */
  +    public DTMAxisIterator setStartNode(int node)
  +    {
  +
  +      if (_isRestartable)
  +      {
  +        _startNode = getDocument();
  +        _currentNode = NULL;
  +
  +        return resetPosition();
  +      }
  +
  +      return this;
  +    }
  +
  +    /**
  +     * Get the next node in the iteration.
  +     *
  +     * @return The next node handle in the iteration, or END.
  +     */
  +    public int next()
  +    {
  +      if(_startNode == _currentNode)
  +        return NULL;
  +
  +      _currentNode = _startNode;
  +
  +      return returnNode(_startNode);
  +    }
  +  }  // end of RootIterator
  +  
  +  /**
  +   * Iterator that returns the namespace nodes as defined by the XPath data 
model 
  +   * for a given node, filtered by extended type ID.
  +   */
  +  private class TypedRootIterator extends RootIterator
  +  {
  +
  +    /** The extended type ID that was requested. */
  +    private final int _nodeType;
  +
  +    /**
  +     * Constructor TypedRootIterator
  +     *
  +     * @param nodeType The extended type ID being requested.
  +     */
  +    public TypedRootIterator(int nodeType)
  +    {
  +      super();
  +      _nodeType = nodeType;
  +    }
  +
  +    /**
  +     * Get the next node in the iteration.
  +     *
  +     * @return The next node handle in the iteration, or END.
  +     */
  +    public int next()
  +    {
  +
  +      for (int node = super.next(); node != END; node = super.next())
  +      {
  +        if (getExpandedTypeID(node) == _nodeType)
  +        {
  +          _currentNode = node;
   
  +          return returnNode(node);
  +        }
  +      }
  +
  +      return END;
  +    }
  +  }  // end of TypedRootIterator
  +
     /**
      * Iterator that returns attributes within a given namespace for a node.
      */
  @@ -791,9 +998,6 @@
     private class PrecedingSiblingIterator extends InternalAxisIteratorBase
     {
   
  -    /** The start node (...on the left of the graph, I think. -sb) */
  -    private int _start;
  -
       /**
        * True if this iterator has a reversed axis.
        *
  @@ -814,11 +1018,13 @@
        */
       public DTMAxisIterator setStartNode(int node)
       {
  -
         if (_isRestartable)
         {
           _startNode = node;
  -        _currentNode = getFirstChild(getParent(node));
  +        if(node == NULL)
  +          _currentNode = node;
  +        else
  +          _currentNode = getFirstChild(getParent(node));
   
           return resetPosition();
         }
  @@ -834,14 +1040,13 @@
       public int next()
       {
   
  -      if (_currentNode == _start)
  +      if (_currentNode == _startNode)
         {
           return NULL;
         }
         else
         {
           final int node = _currentNode;
  -
           _currentNode = getNextSibling(node);
   
           return returnNode(node);
  @@ -1077,14 +1282,12 @@
      */
     private class FollowingIterator extends InternalAxisIteratorBase
     {
  -
  -    /**
  -     * _currentNode precedes search for next. 
  -     *
  -     * NEEDSDOC @param node
  -     *
  -     * NEEDSDOC ($objectName$) @return
  -     */
  +    DTMAxisTraverser m_traverser; // easier for now
  +    
  +    public FollowingIterator()
  +    {
  +      m_traverser = getAxisTraverser(Axis.FOLLOWING);
  +    }
   
       /**
        * Set start to END should 'close' the iterator,
  @@ -1106,7 +1309,7 @@
           // int current;
           // while ((node = getLastChild(current = node)) != NULL){}
           // _currentNode = current;
  -        _currentNode = node;
  +        _currentNode = m_traverser.first(node);
   
           // _currentNode precedes possible following(node) nodes
           return resetPosition();
  @@ -1124,22 +1327,10 @@
       {
   
         int node = _currentNode;
  -
  -      while (END != node)
  -      {
  -        node++;
   
  -        int type = _type(node);
  +      _currentNode = m_traverser.next(_startNode, _currentNode);
   
  -        if (DTM.NAMESPACE_NODE != type && DTM.ATTRIBUTE_NODE != type)
  -        {
  -          _currentNode = node;
  -
  -          return returnNode(_currentNode | m_dtmIdent);
  -        }
  -      }
  -
  -      return returnNode(_currentNode = END);
  +      return returnNode(node);
       }
     }  // end of FollowingIterator
   
  @@ -1186,14 +1377,12 @@
      */
     private class AncestorIterator extends InternalAxisIteratorBase
     {
  +    org.apache.xml.utils.NodeVector m_ancestors = 
  +         new org.apache.xml.utils.NodeVector();
  +         
  +    int m_ancestorsPos;
   
       /**
  -     * _currentNode is the current ancestor index. 
  -     *
  -     * NEEDSDOC ($objectName$) @return
  -     */
  -
  -    /**
        * True if this iterator has a reversed axis.
        *
        * @return true since this iterator is a reversed axis.
  @@ -1261,6 +1450,14 @@
             _startNode = getParent(node);
   
           _currentNode = getDocument();
  +        
  +        node = _startNode;
  +        while (node != END)
  +        {
  +          m_ancestors.addElement(node);
  +          node = getParent(node);
  +        }
  +        m_ancestorsPos = m_ancestors.size()-1;
   
           return resetPosition();
         }
  @@ -1277,7 +1474,7 @@
       public DTMAxisIterator reset()
       {
   
  -      _currentNode = _startNode;
  +      _currentNode = getDocument();
   
         return resetPosition();
       }
  @@ -1291,19 +1488,14 @@
       {
   
         int next = _currentNode;
  -
  -      // The alternative to this is to just allocate a stack in setStartNode.
  -      // Given often next() is only called once, I'm not sure that would 
  -      // be optimal.  -sb
  -      int node = _startNode;
  -
  -      while (node != END && node != _currentNode)
  -      {
  -        _currentNode = node;
  -        node = getParent(node);
  -      }
  -
  -      return (next);
  +      
  +      int pos = m_ancestorsPos--;
  +      if(pos < 0)
  +        _currentNode = DTM.NULL;
  +      else
  +        _currentNode = m_ancestors.elementAt(pos);
  +      
  +      return returnNode(next);
       }
     }  // end of AncestorIterator
   
  @@ -1376,14 +1568,6 @@
     {
   
       /**
  -     * _currentNode precedes search for next, and is identity, not handle 
  -     *
  -     * NEEDSDOC @param node
  -     *
  -     * NEEDSDOC ($objectName$) @return
  -     */
  -
  -    /**
        * Set start to END should 'close' the iterator,
        * i.e. subsequent call to next() should return END.
        *
  @@ -1426,7 +1610,7 @@
        */
       protected boolean isDescendant(int identity)
       {
  -      return _parent(identity) >= _startNode;
  +      return (_startNode == identity) || _parent(identity) >= _startNode;
       }
   
       /**
  
  
  
  1.1.2.4   +77 -19    
xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBaseTraversers.java
  
  Index: DTMDefaultBaseTraversers.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBaseTraversers.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- DTMDefaultBaseTraversers.java     2001/05/25 17:36:31     1.1.2.3
  +++ DTMDefaultBaseTraversers.java     2001/05/27 02:28:46     1.1.2.4
  @@ -524,6 +524,76 @@
      */
     private class FollowingTraverser extends DescendantTraverser
     {
  +    
  +  /**
  +   * Get the first of the following.
  +   *
  +   * @param context The context node of this traversal. This is the point
  +   * that the traversal starts from.
  +   * @return the first node in the traversal.
  +   */
  +  public int first(int context)
  +  {
  +    int first;
  +    int type = getNodeType(context);
  +    if((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
  +    {
  +      context = getParent(context);
  +      first = getFirstChild(context);
  +      if(NULL != first)
  +        return first;
  +    }
  +    do
  +    {
  +      first = getNextSibling(context);
  +      if(NULL == first)
  +        context = getParent(context);
  +    }
  +      while(NULL == first && NULL != context);
  +      
  +    return first;
  +  }
  +
  +  /**
  +   * Get the first of the following.
  +   *
  +   * @param context The context node of this traversal. This is the point
  +   * of origin for the traversal -- its "root node" or starting point.
  +   * @param extendedTypeID The extended type ID that must match.
  +   *
  +   * @return the first node in the traversal.
  +   */
  +  public int first(int context, int extendedTypeID)
  +  {
  +    int first;
  +    int type = getNodeType(context);
  +    if((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
  +    {
  +      context = getParent(context);
  +      first = getFirstChild(context);
  +      if(NULL != first)
  +      {
  +        if(_exptype(first) == extendedTypeID)
  +          return first;
  +        else return next(context, first, extendedTypeID);
  +      }
  +    }
  +    do
  +    {
  +      first = getNextSibling(context);
  +      if(NULL == first)
  +        context = getParent(context);
  +      else
  +      {
  +        if(_exptype(first) == extendedTypeID)
  +          return first;
  +        else return next(context, first, extendedTypeID);
  +      }
  +    }
  +      while(NULL == first && NULL != context);
  +      
  +    return first;
  +  }
   
       /**
        * Traverse to the next node after the current node.
  @@ -536,15 +606,9 @@
       public int next(int context, int current)
       {
   
  -      int subtreeRootIdent = context & m_mask;
  -
  -      if (context == current)
  -        current = getNextSibling(context) & m_mask;
  -      else
  -        current = (current & m_mask) + 1;
  -
  -      for (; ; current++)
  +      while (true)
         {
  +        current++;
           int type = _type(current);  // may call nextNode()
   
           if (NULL == type)
  @@ -569,22 +633,16 @@
        */
       public int next(int context, int current, int extendedTypeID)
       {
  -
  -      int subtreeRootIdent = context & m_mask;
  -
  -      if (context == current)
  -        current = getNextSibling(context) & m_mask;
  -      else
  -        current = (current & m_mask) + 1;
   
  -      for (; ; current++)
  +      while (true)
         {
  -        int exptype = _exptype(current);  // may call nextNode()
  +        current++;
  +        int etype = _exptype(current);  // may call nextNode()
   
  -        if (NULL == exptype)
  +        if (NULL == etype)
             return NULL;
   
  -        if (exptype != extendedTypeID)
  +        if (etype != extendedTypeID)
             continue;
   
           return (current | m_dtmIdent);  // make handle.
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.7.2.2   +0 -5      
xml-xalan/java/src/org/apache/xpath/axes/AttributeIterator.java
  
  Index: AttributeIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/AttributeIterator.java,v
  retrieving revision 1.7.2.1
  retrieving revision 1.7.2.2
  diff -u -r1.7.2.1 -r1.7.2.2
  --- AttributeIterator.java    2001/04/10 18:45:14     1.7.2.1
  +++ AttributeIterator.java    2001/05/27 02:28:47     1.7.2.2
  @@ -63,11 +63,6 @@
   import org.apache.xpath.patterns.NodeTest;
   import org.apache.xpath.objects.XObject;
   
  -//import org.w3c.dom.traversal.NodeIterator;
  -//import org.w3c.dom.Node;
  -//import org.w3c.dom.NamedNodeMap;
  -//import org.w3c.dom.DOMException;
  -//import org.w3c.dom.traversal.NodeFilter;
   import org.apache.xml.dtm.DTM;
   import org.apache.xml.dtm.DTMIterator;
   import org.apache.xml.dtm.DTMFilter;
  
  
  
  1.18.2.7  +13 -355   xml-xalan/java/src/org/apache/xpath/axes/AxesWalker.java
  
  Index: AxesWalker.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/AxesWalker.java,v
  retrieving revision 1.18.2.6
  retrieving revision 1.18.2.7
  diff -u -r1.18.2.6 -r1.18.2.7
  --- AxesWalker.java   2001/05/22 05:48:47     1.18.2.6
  +++ AxesWalker.java   2001/05/27 02:28:48     1.18.2.7
  @@ -95,6 +95,11 @@
     {
       super( locPathIterator );
     }
  +  
  +  public final WalkingIterator wi()
  +  {
  +    return (WalkingIterator)m_lpi;
  +  }
   
     /**
      * Initialize an AxesWalker during the parse of the XPath expression.
  @@ -163,7 +168,7 @@
      * @return non-null clone, which may be a new clone, or may be a clone 
      *         contained on the cloneList.
      */
  -  AxesWalker cloneDeep(LocPathIterator cloneOwner, Vector cloneList)
  +  AxesWalker cloneDeep(WalkingIterator cloneOwner, Vector cloneList)
        throws CloneNotSupportedException
     {
       AxesWalker clone = findClone(this, cloneList);
  @@ -177,7 +182,7 @@
         cloneList.addElement(clone);
       }
       
  -    if(m_lpi.m_lastUsedWalker == this)
  +    if(wi().m_lastUsedWalker == this)
         cloneOwner.m_lastUsedWalker = clone;
         
       if(null != m_nextWalker)
  @@ -306,7 +311,7 @@
     public void setRoot(int root)
     {
       // %OPT% Get this directly from the lpi.
  -    m_dtm = m_lpi.getXPathContext().getDTM(root);
  +    m_dtm = wi().getXPathContext().getDTM(root);
       m_isFresh = true;
       m_isDone = false;
       m_root = root;
  @@ -705,28 +710,6 @@
   
         System.out.print(" " + this.toString() + ", "
                          + nodeToString(this.m_currentNode));
  -      printWaiters();
  -    }
  -  }
  -
  -  /**
  -   * Diagnostics.
  -   */
  -  private void printWaiters()
  -  {
  -
  -    if (DEBUG_WAITING)
  -    {
  -      int nWaiting = m_lpi.getWaitingCount();
  -
  -      for (int i = m_lpi.m_waitingBottom; i < nWaiting; i++)
  -      {
  -        AxesWalker ws = (AxesWalker) m_lpi.getWaiting(i);
  -
  -        printDebug("[" + ws.toString() + " WAITING... ]");
  -      }
  -
  -      printDebug("Waiting count: " + nWaiting);
       }
     }
   
  @@ -752,260 +735,6 @@
     }
   
     /**
  -   * Tell if it's OK to traverse to the next node, following document
  -   * order, or if the walker should wait for a condition to occur.
  -   * 
  -   * @param prevStepWalker The previous walker in the location path.
  -   * @param testWalker The walker being tested, but the state may not be 
intact,
  -   * so only static information can be obtained from it.
  -   * @param currentTestNode The current node being testing.
  -   * @param nextLevelAmount An estimation of the next level to traverse to.
  -   *
  -   * @return True if it's OK for testWalker to traverse to nextLevelAmount.
  -   */
  -  protected boolean checkOKToTraverse(AxesWalker prevStepWalker,
  -                                      AxesWalker testWalker,
  -                                      int currentTestNode,
  -                                      int nextLevelAmount)
  -  {
  -
  -    int level = getDTM(currentTestNode).getLevel(currentTestNode);
  -
  -    // Is this always the context node of the test walker?
  -    int prevNode = prevStepWalker.m_currentNode;
  -
  -    // Can the previous walker go past the one being tested?
  -    if (DEBUG_WAITING)
  -      printDebug("[prevStepWalker.getLevelMax():"
  -                 + prevStepWalker.getLevelMax() + " > level:" + level + 
"?]");
  -
  -    boolean ok;
  -
  -    if (!prevStepWalker.m_isDone && prevStepWalker.getLevelMax() > level)
  -    {
  -
  -      // Is (prevStepWalker.m_currentNode > the currentTestNode)?
  -      // (Sorry about the reverse logic).
  -      boolean isNodeAfter = !getDTM(prevNode).isNodeAfter(prevNode, 
currentTestNode);
  -
  -      if (DEBUG_WAITING)
  -        printDebug("[isNodeAfter:" + isNodeAfter + "?]");
  -
  -      if (isNodeAfter)
  -      {
  -        int prevStepLevel = getDTM(prevNode).getLevel(prevNode);
  -
  -        // If the previous step walker is below us in the tree, 
  -        // then we have to wait until it pops back up to our level, 
  -        // (if it ever does).
  -        if (DEBUG_WAITING)
  -          printDebug("[prevStepLevel:" + prevStepLevel + " <= (level:"
  -                     + level + "+nextLevelAmount:" + nextLevelAmount + "):"
  -                     + (level + nextLevelAmount) + "?]");
  -
  -        if (prevStepLevel > (level + nextLevelAmount))
  -        {
  -
  -          // if next step is down, then ok = true, else
  -          // if next step is horizontal, then we have to wait.
  -          ok = false;
  -        }
  -        else
  -          ok = true;
  -      }
  -      else
  -        ok = false;
  -    }
  -    else
  -      ok = true;
  -
  -    if (DEBUG_WAITING)
  -      printDebug("checkOKToTraverse = " + ok);
  -
  -    return ok;
  -  }
  -
  -  /**
  -   * Check if any walkers need to fire before the given walker.  If they
  -   * do, then the given walker will be put on the waiting list, and the
  -   * waiting walker will be returned.
  -   * @param walker The walker that is about to call nextNode(), or null.
  -   * @return walker argument or new walker.
  -   */
  -  AxesWalker checkWaiting(AxesWalker walker)
  -  {
  -
  -    // printDebug("checkWaiting: "+walker.toString()+", 
"+nodeToString(walker.m_currentNode));
  -    if ((null != walker) && (DTM.NULL == walker.m_currentNode))
  -      return walker;
  -
  -    int nWaiting = m_lpi.getWaitingCount();
  -
  -    for (int i = m_lpi.m_waitingBottom; i < nWaiting; i++)
  -    {
  -      AxesWalker ws = (AxesWalker) m_lpi.getWaiting(i);
  -      AxesWalker prevStepWalker = ws.m_prevWalker;
  -
  -      if (null != prevStepWalker)
  -      {
  -        if (DEBUG_WAITING)
  -          printDebug("Calling checkOKToTraverse(" + prevStepWalker.toString()
  -                     + ", " + ws.toString() + ", .);");
  -
  -        if (checkOKToTraverse(prevStepWalker, ws, ws.m_currentNode,
  -                              ws.m_nextLevelAmount))
  -        {
  -          if (null != walker)
  -          {
  -            AxesWalker deferedWalker = walker;
  -
  -            if (!isWaiting(deferedWalker))
  -            {
  -              addToWaitList(deferedWalker);
  -            }
  -          }
  -
  -          walker = ws;
  -
  -          m_lpi.removeFromWaitList(walker);
  -
  -          if (DEBUG_WAITING)
  -            printDebug("[And using WAITING on " + ws.toString());
  -
  -          walker.printEntryDebug();
  -
  -          m_didSwitch = true;
  -
  -          break;
  -        }
  -      }
  -    }
  -
  -    return walker;
  -  }
  -
  -  /**
  -   * We have to do something to get things moving along,
  -   * so get the earliest (in doc order) waiter.
  -   *
  -   * @return the earliest (in doc order) waiting walker.
  -   */
  -  private AxesWalker getEarliestWaiting()
  -  {
  -
  -    AxesWalker first = null;
  -    int nWaiting = m_lpi.getWaitingCount();
  -
  -    for (int i = m_lpi.m_waitingBottom; i < nWaiting; i++)
  -    {
  -      AxesWalker ws = (AxesWalker) m_lpi.getWaiting(i);
  -
  -      if (first == null)
  -        first = ws;
  -      else
  -      {
  -        if (!getDTM(ws.m_currentNode).isNodeAfter(ws.m_currentNode, 
first.m_currentNode))
  -          first = ws;
  -      }
  -    }
  -
  -    if (null != first)
  -    {
  -      m_lpi.removeFromWaitList(first);
  -
  -      if (DEBUG_WAITING)
  -        printDebug("[(getEarliestWaiting)Using WAITING on "
  -                   + first.toString());
  -
  -      first.printEntryDebug();
  -    }
  -
  -    return first;
  -  }
  -
  -  /**
  -   * Tell if the given walker is already on the waiting list.
  -   *
  -   * @param walker Reference to walker that is the subject of the test.
  -   *
  -   * @return  True if the walker argument is on the waiting list.
  -   */
  -  boolean isWaiting(AxesWalker walker)
  -  {
  -
  -    int nWaiting = m_lpi.getWaitingCount();
  -
  -    for (int i = m_lpi.m_waitingBottom; i < nWaiting; i++)
  -    {
  -      AxesWalker ws = (AxesWalker) m_lpi.getWaiting(i);
  -
  -      if (ws == walker)
  -        return true;
  -    }
  -
  -    return false;
  -  }
  -  
  -  private final void addToWaitList(AxesWalker walker)
  -  {
  -      if (DEBUG_WAITING)
  -        printDebug("[Moving " + walker.toString() + ", "
  -                   + nodeToString(walker.m_currentNode)
  -                   + " to WAITING list]");
  -                   
  -      m_lpi.addToWaitList(walker);
  -  }
  -
  -  /**
  -   * Check if a given walker needs to wait for the previous walker to
  -   * catch up.
  -   *
  -   * @param walker The walker being checked.
  -   *
  -   * @return The walker or the previous walker.
  -   */
  -  AxesWalker checkNeedsToWait(AxesWalker walker)
  -  {
  -
  -    AxesWalker prevWalker = walker.m_prevWalker;
  -
  -    if (null != prevWalker)
  -    {
  -      if (DEBUG_WAITING)
  -        printDebug("Calling checkOKToTraverse(" + prevWalker.toString()
  -                   + ", " + walker.toString() + ", .);");
  -
  -      if (!checkOKToTraverse(prevWalker, walker, walker.m_currentNode,
  -                             walker.m_nextLevelAmount))
  -      {
  -        if (DEBUG_WAITING)
  -          printDebug("[Adding " + walker.toString() + " to WAITING list");
  -
  -        if (isWaiting(walker))
  -        {
  -          try
  -          {
  -            if (DEBUG_WAITING)
  -              printDebug("checkNeedsToWait.clone: " + walker.toString());
  -
  -            addToWaitList((AxesWalker) walker.clone());
  -          }
  -          catch (CloneNotSupportedException cnse){}
  -        }
  -        else
  -          addToWaitList(walker);
  -
  -        walker = walker.m_prevWalker;
  -        
  -        if (DEBUG_WAITING)
  -          walker.printEntryDebug();
  -      }
  -    }
  -
  -    return walker;
  -  }
  -
  -  /**
      * Get the next node in document order on the axes.
      *
      * @return the next node in document order on the axes, or null.
  @@ -1065,44 +794,12 @@
       }
   
       int nextNode = DTM.NULL;
  -    AxesWalker walker = m_lpi.getLastUsedWalker();
  -
  -    // DOMHelper dh = m_lpi.getDOMHelper();
  -    // walker.printEntryDebug();
  -    m_didSwitch = false;
  -
  -    boolean processWaiters = true;
  +    AxesWalker walker = wi().getLastUsedWalker();
   
       do
       {
         while (true)
         {
  -
  -        // Check to see if there's any walkers that need to execute first.
  -        if (processWaiters)
  -        {
  -          AxesWalker waiting = checkWaiting(walker);
  -
  -          if (m_didSwitch)
  -          {
  -            m_didSwitch = false;
  -            walker = waiting;
  -          }
  -          else if (null != walker)
  -          {
  -            waiting = checkNeedsToWait(walker);
  -
  -            if (waiting != walker)
  -            {
  -              walker = waiting;
  -
  -              continue;
  -            }
  -          }
  -        }
  -        else
  -          processWaiters = true;
  -
           if (null == walker)
             break;
   
  @@ -1115,22 +812,7 @@
           if (DTM.NULL == nextNode)
           {
   
  -          // AxesWalker prev = walker; ?? -sb
             walker = walker.m_prevWalker;
  -
  -          if (null != walker)
  -            walker.printEntryDebug();
  -          else
  -          {
  -            walker = getEarliestWaiting();
  -
  -            if (null != walker)
  -            {
  -              processWaiters = false;
  -
  -              continue;
  -            }
  -          }
           }
           else
           {
  @@ -1158,7 +840,7 @@
                 printDebugAdd(", m_prevReturned: "
                               + nodeToString(m_prevReturned));
   
  -            m_lpi.setLastUsedWalker(walker);
  +            wi().setLastUsedWalker(walker);
   
               // return walker.returnNextNode(nextNode);
               break;
  @@ -1169,31 +851,7 @@
   
               walker = walker.m_nextWalker;
   
  -            /*
  -            if((walker.getRoot() != null) &&
  -            prev.getLevelMax() >= walker.getLevelMax()) // bogus, but might 
be ok
  -            */
  -            if (isWaiting(walker))
  -            {
  -              try
  -              {
  -                walker = (AxesWalker) walker.clone();
  -
  -                // walker.pushState();
  -                // System.out.println("AxesWalker - Calling setRoot(1)");
  -                walker.setRoot(nextNode);
  -
  -                if (DEBUG_WAITING)
  -                  printDebug("clone: " + walker.toString());
  -              }
  -              catch (CloneNotSupportedException cnse){}
  -            }
  -            else
  -            {
  -
  -              // System.out.println("AxesWalker - Calling setRoot(2)");
  -              walker.setRoot(nextNode);
  -            }
  +            walker.setRoot(nextNode);
   
               walker.m_prevWalker = prev;
   
  @@ -1251,7 +909,7 @@
       walker.setNextWalker(null);
       walker.setPrevWalker(null);
   
  -    LocPathIterator lpi = walker.getLocPathIterator();
  +    WalkingIterator lpi = wi();
       AxesWalker savedWalker = lpi.getLastUsedWalker();
   
       try
  @@ -1380,7 +1038,7 @@
     public DTM getDTM(int node)
     {
       //
  -    return m_lpi.getXPathContext().getDTM(node);
  +    return wi().getXPathContext().getDTM(node);
     }
   
     /**
  
  
  
  1.6.2.3   +1 -1      
xml-xalan/java/src/org/apache/xpath/axes/ChildIterator.java
  
  Index: ChildIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildIterator.java,v
  retrieving revision 1.6.2.2
  retrieving revision 1.6.2.3
  diff -u -r1.6.2.2 -r1.6.2.3
  --- ChildIterator.java        2001/05/10 20:48:46     1.6.2.2
  +++ ChildIterator.java        2001/05/27 02:28:48     1.6.2.3
  @@ -83,7 +83,7 @@
      * @param compiler A reference to the Compiler that contains the op map.
      * @param opPos The position within the op map, which contains the
      * location path expression for this itterator.
  -   * NEEDSDOC @param analysis
  +   * @param analysis Analysis bits of the entire pattern.
      *
      * @throws javax.xml.transform.TransformerException
      */
  
  
  
  1.8.2.3   +5 -3      
xml-xalan/java/src/org/apache/xpath/axes/ChildTestIterator.java
  
  Index: ChildTestIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildTestIterator.java,v
  retrieving revision 1.8.2.2
  retrieving revision 1.8.2.3
  diff -u -r1.8.2.2 -r1.8.2.3
  --- ChildTestIterator.java    2001/05/10 20:48:48     1.8.2.2
  +++ ChildTestIterator.java    2001/05/27 02:28:48     1.8.2.3
  @@ -98,9 +98,11 @@
       int whatToShow = compiler.getWhatToShow(firstStepPos);
   
       if ((0 == (whatToShow
  -               & (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_ELEMENT
  -                  | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) 
  -                  || (whatToShow == DTMFilter.SHOW_ALL))
  +               & (DTMFilter.SHOW_ATTRIBUTE 
  +               | DTMFilter.SHOW_NAMESPACE 
  +               | DTMFilter.SHOW_ELEMENT
  +               | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) 
  +               || (whatToShow == DTMFilter.SHOW_ALL))
         initNodeTest(whatToShow);
       else
       {
  
  
  
  1.6.2.3   +3 -3      
xml-xalan/java/src/org/apache/xpath/axes/ChildWalkerMultiStep.java
  
  Index: ChildWalkerMultiStep.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildWalkerMultiStep.java,v
  retrieving revision 1.6.2.2
  retrieving revision 1.6.2.3
  diff -u -r1.6.2.2 -r1.6.2.3
  --- ChildWalkerMultiStep.java 2001/05/17 05:38:48     1.6.2.2
  +++ ChildWalkerMultiStep.java 2001/05/27 02:28:48     1.6.2.3
  @@ -141,7 +141,7 @@
     public int nextNode()
     {
   
  -    AxesWalker walker = m_lpi.getLastUsedWalker();
  +    AxesWalker walker = wi().getLastUsedWalker();
       boolean fast = (null != walker) ? walker.isFastWalker() : false;
   
       while (null != walker)
  @@ -166,7 +166,7 @@
             walker = walker.m_nextWalker;
   
             walker.setRoot(next);
  -          m_lpi.setLastUsedWalker(walker);
  +          wi().setLastUsedWalker(walker);
             fast = walker.isFastWalker();
           }
           else
  @@ -178,7 +178,7 @@
   
           if (null != walker)
             fast = walker.isFastWalker();
  -        m_lpi.setLastUsedWalker(walker);
  +        wi().setLastUsedWalker(walker);
         }
       }
   
  
  
  
  1.8.2.5   +1 -4      
xml-xalan/java/src/org/apache/xpath/axes/DescendantIterator.java
  
  Index: DescendantIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/DescendantIterator.java,v
  retrieving revision 1.8.2.4
  retrieving revision 1.8.2.5
  diff -u -r1.8.2.4 -r1.8.2.5
  --- DescendantIterator.java   2001/05/10 20:48:50     1.8.2.4
  +++ DescendantIterator.java   2001/05/27 02:28:49     1.8.2.5
  @@ -100,8 +100,7 @@
       int firstStepPos = compiler.getFirstChildPos(opPos);
       int stepType = ops[firstStepPos];
   
  -    if (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType)
  -      m_orSelf = true;
  +    m_orSelf = (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType);
       if (OpCodes.FROM_SELF == stepType)
       {
         m_orSelf = true;
  @@ -113,8 +112,6 @@
         m_orSelf = true;
         firstStepPos += 8;
       }
  -    else
  -      m_orSelf = false;
   
       int whatToShow = compiler.getWhatToShow(firstStepPos);
   
  
  
  
  1.14.2.5  +1 -1      
xml-xalan/java/src/org/apache/xpath/axes/FilterExprWalker.java
  
  Index: FilterExprWalker.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/FilterExprWalker.java,v
  retrieving revision 1.14.2.4
  retrieving revision 1.14.2.5
  diff -u -r1.14.2.4 -r1.14.2.5
  --- FilterExprWalker.java     2001/05/22 05:48:47     1.14.2.4
  +++ FilterExprWalker.java     2001/05/27 02:28:49     1.14.2.5
  @@ -89,7 +89,7 @@
      *
      * @param locPathIterator non-null reference to the parent iterator.
      */
  -  public FilterExprWalker(LocPathIterator locPathIterator)
  +  public FilterExprWalker(WalkingIterator locPathIterator)
     {
       super(locPathIterator);
     }
  
  
  
  1.24.2.8  +43 -286   
xml-xalan/java/src/org/apache/xpath/axes/LocPathIterator.java
  
  Index: LocPathIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/LocPathIterator.java,v
  retrieving revision 1.24.2.7
  retrieving revision 1.24.2.8
  diff -u -r1.24.2.7 -r1.24.2.8
  --- LocPathIterator.java      2001/05/23 02:57:40     1.24.2.7
  +++ LocPathIterator.java      2001/05/27 02:28:49     1.24.2.8
  @@ -95,40 +95,11 @@
    * the case where the LocPathIterator is "owned" by a UnionPathIterator,
    * in which case the UnionPathIterator will cache the nodes.</p>
    */
  -public class LocPathIterator extends PredicatedNodeTest
  +public abstract class LocPathIterator extends PredicatedNodeTest
           implements Cloneable, DTMIterator, java.io.Serializable
   {
   
     /**
  -   * Get the waiting walker at the given index.
  -   *
  -   *
  -   * @param i The walker index.
  -   *
  -   * @return non-null reference to an AxesWalker.
  -   */
  -  AxesWalker getWaiting(int i)
  -  {
  -    return (AxesWalker) m_waiting.elementAt(i);
  -  }
  -
  -  /**
  -   * Get the number of waiters waiting in the current expression execution.
  -   * Note that this may not be the same as the total number of waiters in
  -   * the waiting list.
  -   *
  -   *
  -   * @return the number of waiters waiting in the current expression 
execution.
  -   */
  -  int getWaitingCount()
  -  {
  -    if(null == m_waiting)
  -      return 0;
  -    else
  -      return m_waiting.size() - m_waitingBottom;
  -  }
  -
  -  /**
      * Create a LocPathIterator object.
      *
      * @param nscontext The namespace context for this iterator,
  @@ -179,18 +150,7 @@
             Compiler compiler, int opPos, int analysis, boolean 
shouldLoadWalkers)
               throws javax.xml.transform.TransformerException
     {
  -    m_analysis = analysis;
  -
       setLocPathIterator(this);
  -
  -    int firstStepPos = compiler.getFirstChildPos(opPos);
  -
  -    if (shouldLoadWalkers)
  -    {
  -      m_firstWalker = WalkerFactory.loadWalkers(this, compiler, firstStepPos,
  -                                                0);
  -      m_lastUsedWalker = m_firstWalker;
  -    }
     }
     
     /**
  @@ -659,47 +619,23 @@
   
       return clone;
     }
  -
  -  /**
  -   * Get a cloned LocPathIterator that holds the same
  -   * position as this iterator.
  -   *
  -   * @return A clone of this iterator that holds the same node position.
  -   *
  -   * @throws CloneNotSupportedException
  -   */
  -  public Object clone() throws CloneNotSupportedException
  -  {
  -
  -    LocPathIterator clone = (LocPathIterator) super.clone();
  -
  -    //    clone.m_varStackPos = this.m_varStackPos;
  -    //    clone.m_varStackContext = this.m_varStackContext;
  -    if (null != m_firstWalker)
  -    {
  -      // If we have waiting walkers, we have to check for duplicates.
  -      Vector clones = (null != m_waiting) ? new Vector() : null;
  -
  -      clone.m_firstWalker = m_firstWalker.cloneDeep(clone, clones);
  -
  -      if (null != m_waiting)
  -      {
  -        clone.m_waiting = (Vector) m_waiting.clone();  // or is new Vector 
faster?
   
  -        int n = m_waiting.size();
  +//  /**
  +//   * Get a cloned LocPathIterator that holds the same
  +//   * position as this iterator.
  +//   *
  +//   * @return A clone of this iterator that holds the same node position.
  +//   *
  +//   * @throws CloneNotSupportedException
  +//   */
  +//  public Object clone() throws CloneNotSupportedException
  +//  {
  +//
  +//    LocPathIterator clone = (LocPathIterator) super.clone();
  +//
  +//    return clone;
  +//  }
   
  -        for (int i = 0; i < n; i++)
  -        {
  -          AxesWalker waiting = (AxesWalker) m_waiting.elementAt(i);
  -
  -          clone.m_waiting.setElementAt(waiting.cloneDeep(clone, clones), i);
  -        }
  -      }
  -    }
  -
  -    return clone;
  -  }
  -
     /**
      * Reset the iterator.
      */
  @@ -711,16 +647,6 @@
       m_lastFetched = DTM.NULL;
       m_next = 0;
       m_last = 0;
  -    m_waitingBottom = 0;
  -
  -    if (null != m_firstWalker)
  -    {
  -      m_lastUsedWalker = m_firstWalker;
  -
  -      m_firstWalker.setRoot(m_context);
  -      if(null != m_waiting)
  -        m_waiting.removeAllElements();
  -    }
     }
   
     /**
  @@ -730,69 +656,7 @@
      * @return  The next <code>Node</code> in the set being iterated over, or
      *   <code>null</code> if there are no more members in that set.
      */
  -  public int nextNode()
  -  {
  -
  -    // If the cache is on, and the node has already been found, then 
  -    // just return from the list.
  -    if ((null != m_cachedNodes)
  -            && (m_next < m_cachedNodes.size()))
  -    {
  -      int next = m_cachedNodes.elementAt(m_next);
  -    
  -      incrementNextPosition();
  -      m_currentContextNode = next;
  -
  -      return next;
  -    }
  -
  -    // If the variable stack position is not -1, we'll have to 
  -    // set our position in the variable stack, so our variable access 
  -    // will be correct.  Iterators that are at the top level of the 
  -    // expression need to reset the variable stack, while iterators 
  -    // in predicates do not need to, and should not, since their execution
  -    // may be much later than top-level iterators.  
  -    // m_varStackPos is set in initContext, which is called 
  -    // from the execute method.
  -    if (-1 == m_varStackPos)
  -    {
  -      if (DTM.NULL == m_firstWalker.getRoot())
  -      {
  -        this.setNextPosition(0);
  -        m_firstWalker.setRoot(m_context);
  -
  -        m_lastUsedWalker = m_firstWalker;
  -      }
  -
  -      return returnNextNode(m_firstWalker.nextNode());
  -    }
  -    else
  -    {
  -      VariableStack vars = m_execContext.getVarStack();
  -
  -      // These three statements need to be combined into one operation.
  -      int savedStart = vars.getSearchStart();
  -
  -      vars.setSearchStart(m_varStackPos);
  -      vars.pushContextPosition(m_varStackContext);
  -
  -      if (DTM.NULL == m_firstWalker.getRoot())
  -      {
  -        this.setNextPosition(0);
  -        m_firstWalker.setRoot(m_context);
  -
  -        m_lastUsedWalker = m_firstWalker;
  -      }
  -
  -      int n = returnNextNode(m_firstWalker.nextNode());
  -
  -      // These two statements need to be combined into one operation.
  -      vars.setSearchStart(savedStart);
  -      vars.popContextPosition();
  -
  -      return n;
  -    }
  -  }
  +  public abstract int nextNode();
   
     /**
      * Bottleneck the return of a next node, to make returns
  @@ -863,74 +727,6 @@
     }
   
     /**
  -   * <meta name="usage" content="advanced"/>
  -   * Get the head of the walker list.
  -   *
  -   * @return The head of the walker list, or null
  -   * if this iterator does not implement walkers.
  -   */
  -  public final AxesWalker getFirstWalker()
  -  {
  -    return m_firstWalker;
  -  }
  -
  -  /**
  -   * <meta name="usage" content="advanced"/>
  -   * Set the last used walker.
  -   *
  -   * @param walker The last used walker, or null.
  -   */
  -  public final void setLastUsedWalker(AxesWalker walker)
  -  {
  -    m_lastUsedWalker = walker;
  -  }
  -
  -  /**
  -   * <meta name="usage" content="advanced"/>
  -   * Get the last used walker.
  -   *
  -   * @return The last used walker, or null.
  -   */
  -  public final AxesWalker getLastUsedWalker()
  -  {
  -    return m_lastUsedWalker;
  -  }
  -
  -  /**
  -   * <meta name="usage" content="advanced"/>
  -   * Add a walker to the waiting list.
  -   *
  -   * @param walker A walker that is waiting for
  -   * other step walkers to complete, before it can
  -   * continue.
  -   *
  -   * @see org.apache.xpath.axes.AxesWalker
  -   */
  -  public final void addToWaitList(AxesWalker walker)
  -  {
  -    if (null == m_waiting)
  -    {
  -      m_waiting = new Vector();
  -    }
  -    
  -    m_waiting.addElement(walker);
  -  }
  -
  -  /**
  -   * <meta name="usage" content="advanced"/>
  -   * Remove a walker from the waiting list.
  -   *
  -   * @param walker A walker that is no longer waiting.
  -   *
  -   * @see org.apache.xpath.axes.AxesWalker
  -   */
  -  public final void removeFromWaitList(AxesWalker walker)
  -  {
  -    if(null != m_waiting) // defensive check.
  -      m_waiting.removeElement(walker);
  -  }
  -
  -  /**
      * Tells if we've found the last node yet.
      *
      * @return true if the last nextNode returned null.
  @@ -1066,48 +862,26 @@
       // System.out.println("pos: "+pos);
       return pos;
     }
  -  
  -  /**
  -   * Get the analysis pattern built by the WalkerFactory.
  -   *
  -   * @return The analysis pattern built by the WalkerFactory.
  -   */
  -  int getAnalysis()
  -  {
  -    return m_analysis;
  -  }
  -
  -  /**
  -   * Set the analysis pattern built by the WalkerFactory.
  -   *
  -   * @param a The analysis pattern built by the WalkerFactory.
  -   */
  -  void setAnalysis(int a)
  -  {
  -    m_analysis = a;
  -  }
     
  -  /**
  -   * Tell if this expression or it's subexpressions can traverse outside 
  -   * the current subtree.
  -   * 
  -   * @return true if traversal outside the context node's subtree can occur.
  -   */
  -   public boolean canTraverseOutsideSubtree()
  -   {
  -    if((m_analysis & WalkerFactory.BITMASK_TRAVERSES_OUTSIDE_SUBTREE) != 0)
  -    {
  -      return true;
  -    }
  -    // We have to ask subwalkers about their predicates.
  -    if(null != m_firstWalker)
  -    {
  -      if(m_firstWalker.canTraverseOutsideSubtree())
  -        return true;
  -    }
  -    return super.canTraverseOutsideSubtree();
  -   }
  -
  +//  /**
  +//   * Get the analysis pattern built by the WalkerFactory.
  +//   *
  +//   * @return The analysis pattern built by the WalkerFactory.
  +//   */
  +//  int getAnalysis()
  +//  {
  +//    return m_analysis;
  +//  }
  +
  +//  /**
  +//   * Set the analysis pattern built by the WalkerFactory.
  +//   *
  +//   * @param a The analysis pattern built by the WalkerFactory.
  +//   */
  +//  void setAnalysis(int a)
  +//  {
  +//    m_analysis = a;
  +//  }
     
     //============= State Data =============
     
  @@ -1117,9 +891,6 @@
      */
     transient protected DTM m_cdtm;
     
  -  /** The starting point in m_waiting where the waiting step walkers are. */
  -  transient int m_waitingBottom = 0;
  -
     /**
      * An index to the point in the variable stack where we should
      * begin variable searches for this iterator.
  @@ -1160,14 +931,6 @@
      */
     transient NodeSet m_cachedNodes;
   
  -  /** The last used step walker in the walker list.
  -   *  @serial */
  -  protected AxesWalker m_lastUsedWalker;
  -
  -  /** The head of the step walker list.
  -   *  @serial */
  -  protected AxesWalker m_firstWalker;
  -
     /** This is true if nextNode returns null. */
     transient protected boolean m_foundLast = false;
   
  @@ -1205,17 +968,11 @@
      */
     transient protected int m_next = 0;
   
  -  /**
  -   * The list of "waiting" step walkers.
  -   * @see org.apache.xpath.axes.AxesWalker
  -   */
  -  transient private Vector m_waiting = null;
  -  
  -  /**
  -   * The analysis pattern built by the WalkerFactory.
  -   * TODO: Move to LocPathIterator.
  -   * @see org.apache.xpath.axes.WalkerFactory
  -   * @serial
  -   */
  -  protected int m_analysis = 0x00000000;
  +//  /**
  +//   * The analysis pattern built by the WalkerFactory.
  +//   * TODO: Move to LocPathIterator.
  +//   * @see org.apache.xpath.axes.WalkerFactory
  +//   * @serial
  +//   */
  +//  protected int m_analysis = 0x00000000;
   }
  
  
  
  1.1.2.3   +10 -75    
xml-xalan/java/src/org/apache/xpath/axes/Attic/MatchPatternIterator.java
  
  Index: MatchPatternIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/Attic/MatchPatternIterator.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- MatchPatternIterator.java 2001/05/25 17:36:43     1.1.2.2
  +++ MatchPatternIterator.java 2001/05/27 02:28:49     1.1.2.3
  @@ -90,7 +90,7 @@
     protected StepPattern m_pattern;
   
     /** The traversal axis from where the nodes will be filtered. */
  -  protected int m_superAxes = -1;
  +  protected int m_superAxis = -1;
   
     /** The DTM inner traversal class, that corresponds to the super axis. */
     protected DTMAxisTraverser m_traverser;
  @@ -122,45 +122,7 @@
   
       int firstStepPos = compiler.getFirstChildPos(opPos);
   
  -    m_pattern = WalkerFactory.loadSteps(this, compiler, firstStepPos, 0);
  -    
  -//    int axis = -1;
  -//    int attributeAxis = -1;
  -//    int namespaceAxis = -1;
  -//    
  -//    if(0 != (analysis & WalkerFactory.BIT_ATTRIBUTE))
  -//    {
  -//      attributeAxis = Axis.ATTRIBUTE;
  -//    }
  -//    if(0 != (analysis & WalkerFactory.BIT_ATTRIBUTE))
  -//    {
  -//      namespaceAxis = Axis.NAMESPACE;
  -//    }
  -//    if(0 != (analysis & WalkerFactory.BIT_CHILD))
  -//    {
  -//      axis = Axis.CHILD; 
  -//    }
  -//    if(0 != (analysis & WalkerFactory.BIT_DESCENDANT))
  -//    {
  -//      if(attributeAxis != -1)
  -//      {
  -//        axis = Axis.ALLFROMNODE;
  -//        attributeAxis = -1;
  -//      }
  -//      else
  -//        axis = Axis.DESCENDANT; 
  -//    }
  -//    if(0 != (analysis & WalkerFactory.BIT_DESCENDANT_OR_SELF))
  -//    {
  -//      if(attributeAxis != -1)
  -//      {
  -//        axis = Axis.ALLFROMNODE;
  -//        attributeAxis = -1;
  -//      }
  -//      else
  -//        axis = Axis.DESCENDANTORSELF;
  -//    }
  -    
  +    m_pattern = WalkerFactory.loadSteps(this, compiler, firstStepPos, 0); 
   
       boolean fromRoot = false;
       boolean walkBack = false;
  @@ -201,31 +163,31 @@
       {
         if(walkAttributes)
         {
  -        m_superAxes = Axis.ALL;
  +        m_superAxis = Axis.ALL;
         }
         else
         {
  -        m_superAxes = Axis.DESCENDANTSFROMROOT;
  +        m_superAxis = Axis.DESCENDANTSFROMROOT;
         }
       }
       else if(walkDescendants)
       {
         if(walkAttributes)
         {
  -        m_superAxes = Axis.ALLFROMNODE;
  +        m_superAxis = Axis.ALLFROMNODE;
         }
         else
         {
  -        m_superAxes = Axis.DESCENDANTORSELF;
  +        m_superAxis = Axis.DESCENDANTORSELF;
         }
       }
       else
       {
  -      m_superAxes = Axis.ALL;
  +      m_superAxis = Axis.ALL;
       }
       if(false || DEBUG)
       {
  -      System.out.println("axis: "+Axis.names[m_superAxes]);
  +      System.out.println("axis: "+Axis.names[m_superAxis]);
       }
       
     }
  @@ -240,7 +202,7 @@
     public void initContext(XPathContext execContext)
     {
       super.initContext(execContext);
  -    m_traverser = m_cdtm.getAxisTraverser(m_superAxes);
  +    m_traverser = m_cdtm.getAxisTraverser(m_superAxis);
     }
     
     /**
  @@ -249,33 +211,6 @@
      */
     protected int getNextNode()
     {
  -//    if(m_superAxes == Axis.ALL || m_superAxes == Axis.ALLFROMNODE)
  -//    {
  -//      if(DTM.NULL != m_nsElemBase)
  -//      {
  -//        m_lastFetched = m_cdtm.getNextNamespaceNode(m_nsElemBase, 
m_lastFetched, true);
  -//        if(DTM.NULL != m_lastFetched)
  -//        {
  -//          return m_lastFetched;
  -//        }
  -//        else
  -//        {
  -//          m_lastFetched = m_nsElemBase;
  -//          m_nsElemBase = DTM.NULL;
  -//        }
  -//      }
  -//      else if(DTM.NULL != m_lastFetched 
  -//           && DTM.ELEMENT_NODE == m_cdtm.getNodeType(m_lastFetched))
  -//      {
  -//        int ns = m_cdtm.getFirstNamespaceNode(m_lastFetched, true);
  -//        if(DTM.NULL != ns)
  -//        {
  -//          m_nsElemBase = m_lastFetched;
  -//          m_lastFetched = ns;
  -//          return m_lastFetched;
  -//        }
  -//      }
  -//    }
       m_lastFetched = (DTM.NULL == m_lastFetched)
                        ? m_traverser.first(m_context)
                        : m_traverser.next(m_context, m_lastFetched);
  @@ -417,7 +352,7 @@
         
         if(DEBUG)
         {
  -        System.out.println("analysis: "+Integer.toBinaryString(m_analysis));
  +        // System.out.println("analysis: 
"+Integer.toBinaryString(m_analysis));
           System.out.println("score: "+score);
           System.out.println("skip: "+(score == NodeTest.SCORE_NONE));
         }
  
  
  
  1.3.2.3   +1 -14     
xml-xalan/java/src/org/apache/xpath/axes/PredicatedNodeTest.java
  
  Index: PredicatedNodeTest.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/PredicatedNodeTest.java,v
  retrieving revision 1.3.2.2
  retrieving revision 1.3.2.3
  diff -u -r1.3.2.2 -r1.3.2.3
  --- PredicatedNodeTest.java   2001/05/06 02:09:51     1.3.2.2
  +++ PredicatedNodeTest.java   2001/05/27 02:28:50     1.3.2.3
  @@ -281,17 +281,7 @@
         for (int i = 0; i < nPredicates; i++)
         {
           // System.out.println("Executing predicate expression - waiting 
count: "+m_lpi.getWaitingCount());
  -        int savedWaitingBottom = m_lpi.m_waitingBottom;
  -        m_lpi.m_waitingBottom = m_lpi.getWaitingCount();
  -        XObject pred;
  -        try
  -        {
  -          pred = m_predicates[i].execute(xctxt);
  -        }
  -        finally
  -        {
  -          m_lpi.m_waitingBottom = savedWaitingBottom;
  -        }
  +        XObject pred = m_predicates[i].execute(xctxt);
           // System.out.println("\nBack from executing predicate expression - 
waiting count: "+m_lpi.getWaitingCount());
           // System.out.println("pred.getType(): "+pred.getType());
           if (XObject.CLASS_NUMBER == pred.getType())
  @@ -304,7 +294,6 @@
               // System.out.println("getProximityPosition(m_predicateIndex): "
               //                   + getProximityPosition(m_predicateIndex));
               System.out.println("pred.num(): " + pred.num());
  -            System.out.println("waiting count: "+m_lpi.getWaitingCount());
             }
   
             int proxPos = this.getProximityPosition(m_predicateIndex);
  @@ -314,7 +303,6 @@
               {
                 System.out.println("\nnode context: "+nodeToString(context));
                 System.out.println("index predicate is false: "+proxPos);
  -              System.out.println("waiting count: "+m_lpi.getWaitingCount());
                 System.out.println("\n===== end predicate count ========");
               }
               return false;
  @@ -323,7 +311,6 @@
             {
               System.out.println("\nnode context: "+nodeToString(context));
               System.out.println("index predicate is true: "+proxPos);
  -            System.out.println("waiting count: "+m_lpi.getWaitingCount());
               System.out.println("\n===== end predicate count ========");
             }
           }
  
  
  
  1.6.2.3   +6 -6      
xml-xalan/java/src/org/apache/xpath/axes/ReverseAxesWalker.java
  
  Index: ReverseAxesWalker.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ReverseAxesWalker.java,v
  retrieving revision 1.6.2.2
  retrieving revision 1.6.2.3
  diff -u -r1.6.2.2 -r1.6.2.3
  --- ReverseAxesWalker.java    2001/05/06 02:09:51     1.6.2.2
  +++ ReverseAxesWalker.java    2001/05/27 02:28:50     1.6.2.3
  @@ -129,7 +129,7 @@
         
       if (m_proximityPositions[predicateIndex] <= 0)
       {
  -      AxesWalker savedWalker = m_lpi.getLastUsedWalker();
  +      AxesWalker savedWalker = wi().getLastUsedWalker();
   
         try
         {
  @@ -141,7 +141,7 @@
   
           clone.setPrevWalker(null);
           clone.setNextWalker(null);
  -        m_lpi.setLastUsedWalker(clone);
  +        wi().setLastUsedWalker(clone);
   
           // Count 'em all
           int count = 1;
  @@ -161,7 +161,7 @@
         }
         finally
         {
  -        m_lpi.setLastUsedWalker(savedWalker);
  +        wi().setLastUsedWalker(savedWalker);
         }
       }
   
  @@ -192,7 +192,7 @@
     {
   
       int count = 0;
  -    AxesWalker savedWalker = m_lpi.getLastUsedWalker();
  +    AxesWalker savedWalker = wi().getLastUsedWalker();
   
       try
       {
  @@ -204,7 +204,7 @@
   
         clone.setPrevWalker(null);
         clone.setNextWalker(null);
  -      m_lpi.setLastUsedWalker(clone);
  +      wi().setLastUsedWalker(clone);
   
         // Count 'em all
         // count = 1;
  @@ -222,7 +222,7 @@
       }
       finally
       {
  -      m_lpi.setLastUsedWalker(savedWalker);
  +      wi().setLastUsedWalker(savedWalker);
       }
   
       // System.out.println("getLastPos - pos: "+count);
  
  
  
  1.15.2.7  +2 -2      
xml-xalan/java/src/org/apache/xpath/axes/UnionPathIterator.java
  
  Index: UnionPathIterator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/UnionPathIterator.java,v
  retrieving revision 1.15.2.6
  retrieving revision 1.15.2.7
  diff -u -r1.15.2.6 -r1.15.2.7
  --- UnionPathIterator.java    2001/05/22 05:48:47     1.15.2.6
  +++ UnionPathIterator.java    2001/05/27 02:28:50     1.15.2.7
  @@ -486,8 +486,8 @@
         case OpCodes.OP_GROUP :
           loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1);
   
  -        LocPathIterator iter =
  -          new LocPathIterator(compiler.getNamespaceContext());
  +        WalkingIterator iter =
  +          new WalkingIterator(compiler.getNamespaceContext());
             
           if(compiler.getLocationPathDepth() <= 0)
             iter.setIsTopLevel(true);
  
  
  
  1.13.2.5  +583 -61   
xml-xalan/java/src/org/apache/xpath/axes/WalkerFactory.java
  
  Index: WalkerFactory.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/WalkerFactory.java,v
  retrieving revision 1.13.2.4
  retrieving revision 1.13.2.5
  diff -u -r1.13.2.4 -r1.13.2.5
  --- WalkerFactory.java        2001/05/25 17:36:45     1.13.2.4
  +++ WalkerFactory.java        2001/05/27 02:28:50     1.13.2.5
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.compiler.OpCodes;
   import org.apache.xpath.compiler.Compiler;
  +import org.apache.xpath.compiler.FunctionTable;
   import org.apache.xpath.patterns.NodeTest;
   import org.apache.xpath.patterns.StepPattern;
   import org.apache.xpath.patterns.ContextMatchStepPattern;
  @@ -93,7 +94,7 @@
      * @throws javax.xml.transform.TransformerException
      */
     static AxesWalker loadOneWalker(
  -          LocPathIterator lpi, Compiler compiler, int stepOpCodePos)
  +          WalkingIterator lpi, Compiler compiler, int stepOpCodePos)
               throws javax.xml.transform.TransformerException
     {
   
  @@ -131,7 +132,7 @@
      * @throws javax.xml.transform.TransformerException
      */
     static AxesWalker loadWalkers(
  -          LocPathIterator lpi, Compiler compiler, int stepOpCodePos, int 
stepIndex)
  +          WalkingIterator lpi, Compiler compiler, int stepOpCodePos, int 
stepIndex)
               throws javax.xml.transform.TransformerException
     {
   
  @@ -168,10 +169,17 @@
       return firstWalker;
     }
     
  -  public static boolean isSet(int analysis, int bit)
  +  public static boolean isSet(int analysis, int bits)
     {
  -    return (0 != (analysis & bit));
  +    return (0 != (analysis & bits));
     }
  +  
  +  public static void diagnoseIterator(String name, int analysis, Compiler 
compiler)
  +  {
  +    System.out.println(compiler.toString()+", "+name+", "
  +                             + Integer.toBinaryString(analysis) + ", "
  +                             + getAnalysisString(analysis));
  +  }
   
     /**
      * Create a new LocPathIterator iterator.  The exact type of iterator
  @@ -192,22 +200,28 @@
   
       int firstStepPos = compiler.getFirstChildPos(opPos);
       int analysis = analyze(compiler, firstStepPos, 0);
  +    boolean isOneStep = isOneStep(analysis);
   
  +    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
  +    if (isOneStep && walksSelfOnly(analysis) && 
  +        isWild(analysis) && !hasPredicate(analysis))
  +    {
  +      if (DEBUG_ITERATOR_CREATION)
  +        diagnoseIterator("SelfIteratorNoPredicate", analysis, compiler);
  +
  +      // Then use a simple iteration of the attributes, with node test 
  +      // and predicate testing.
  +      return new SelfIteratorNoPredicate(compiler, opPos, analysis);
  +    }
       // Is the iteration exactly one child step?
  -    if ((BIT_CHILD | 0x00000001) == (analysis & (BIT_CHILD | BITS_COUNT)))
  +    else if (walksChildrenOnly(analysis) && isOneStep)
       {
   
  -      //                 BIT_NODETEST_ANY: 1000000000000000000000000000000
  -      //                 BIT_PREDICATE:                      1000000000000
  -      // new iterator:  ChildIterator: 1000000000000010000000000000001, 
node()
         // Does the pattern specify *any* child with no predicate? (i.e. 
select="child::node()".
  -      if ((BIT_NODETEST_ANY == (analysis & BIT_NODETEST_ANY))
  -              &&!(BIT_PREDICATE == (analysis & BIT_PREDICATE)))
  +      if (isWild(analysis) && !hasPredicate(analysis))
         {
           if (DEBUG_ITERATOR_CREATION)
  -          System.out.println("new iterator:  ChildIterator: "
  -                             + Integer.toBinaryString(analysis) + ", "
  -                             + compiler.toString());
  +          diagnoseIterator("ChildIterator", analysis, compiler);
   
           // Use simple child iteration without any test.
           return new ChildIterator(compiler, opPos, analysis);
  @@ -215,28 +229,44 @@
         else
         {
           if (DEBUG_ITERATOR_CREATION)
  -          System.out.println("new iterator:  ChildTestIterator: "
  -                             + Integer.toBinaryString(analysis) + ", "
  -                             + compiler.toString());
  +          diagnoseIterator("ChildTestIterator", analysis, compiler);
   
           // Else use simple node test iteration with predicate test.
           return new ChildTestIterator(compiler, opPos, analysis);
         }
       }
  -
       // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
  -    else if ((BIT_ATTRIBUTE | 0x00000001)
  -             == (analysis & (BIT_ATTRIBUTE | BITS_COUNT)))
  +    else if (isOneStep && walksAttributes(analysis))
       {
         if (DEBUG_ITERATOR_CREATION)
  -        System.out.println("new iterator:  AttributeIterator: "
  -                           + Integer.toBinaryString(analysis) + ", "
  -                           + compiler.toString());
  +        diagnoseIterator("AttributeIterator", analysis, compiler);
   
         // Then use a simple iteration of the attributes, with node test 
         // and predicate testing.
         return new AttributeIterator(compiler, opPos, analysis);
       }
  +    else if(isOneStep && !walksFilteredList(analysis))
  +    {
  +      if( !walksNamespaces(analysis) 
  +      && (walksInDocOrder(analysis) || isSet(analysis, BIT_PARENT)))
  +      {
  +        if (false || DEBUG_ITERATOR_CREATION)
  +          diagnoseIterator("OneStepIteratorForward", analysis, compiler);
  +  
  +        // Then use a simple iteration of the attributes, with node test 
  +        // and predicate testing.
  +        return new OneStepIteratorForward(compiler, opPos, analysis);
  +      }
  +      else
  +      {
  +        if (false || DEBUG_ITERATOR_CREATION)
  +          diagnoseIterator("OneStepIterator", analysis, compiler);
  +  
  +        // Then use a simple iteration of the attributes, with node test 
  +        // and predicate testing.
  +        return new OneStepIterator(compiler, opPos, analysis);
  +      }
  +    }
   
       // Analysis of "//center":
       // bits: 1001000000001010000000000000011
  @@ -250,60 +280,330 @@
       // "//table[3]", because this has to be analyzed as 
       // "/descendant-or-self::node()/table[3]" in order for the indexes 
       // to work right.
  -    else if (0 == (BIT_PREDICATE
  -                   & analysis) && (((BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF
  -                                     | 0x00000001) == (analysis
  -                                       & (BIT_DESCENDANT | 
BIT_DESCENDANT_OR_SELF | BITS_COUNT))) || ((BIT_DESCENDANT_OR_SELF
  -                                         | BIT_SELF
  -                                         | 0x00000002) == (analysis
  -                                           & (BIT_DESCENDANT_OR_SELF
  -                                              | BIT_SELF | BITS_COUNT)))
  -
  -    /* ".//center" -- 1000010000001010000000000000011 */
  -    || ((BIT_DESCENDANT_OR_SELF | BIT_SELF | BIT_CHILD | BIT_NODETEST_ANY
  -            | 0x00000003) == (analysis
  -              & (BIT_DESCENDANT_OR_SELF | BIT_SELF | BIT_CHILD
  -                 | BIT_NODETEST_ANY | BITS_COUNT)))
  -
  -    /* "//center" -- 1001000000001010000000000000011 */
  -    || ((BIT_DESCENDANT_OR_SELF | BIT_ROOT | BIT_CHILD | BIT_NODETEST_ANY
  -            | BIT_ANY_DESCENDANT_FROM_ROOT
  -            | 0x00000003) == (analysis
  -              & (BIT_DESCENDANT_OR_SELF | BIT_ROOT | BIT_CHILD
  -                 | BIT_NODETEST_ANY | BIT_ANY_DESCENDANT_FROM_ROOT
  -                 | BITS_COUNT)))))
  +    else if (isOptimizableForDescendantIterator(compiler, firstStepPos, 0)
  +             && getStepCount(analysis) <= 3 
  +             && walksDescendants(analysis) 
  +             && walksSubtreeOnlyFromRootOrContext(analysis))
       {
         if (DEBUG_ITERATOR_CREATION)
  -        System.out.println("new iterator:  DescendantIterator: "
  -                           + Integer.toBinaryString(analysis) + ", "
  -                           + compiler.toString());
  +        diagnoseIterator("DescendantIterator", analysis, compiler);
   
         return new DescendantIterator(compiler, opPos, analysis);
       }
       else
       { 
  -      if(true || isSet(analysis, BIT_NAMESPACE) || isSet(analysis, 
BIT_FILTER))
  +      if(canCrissCross(analysis) && !isSet(analysis, BIT_NAMESPACE) && 
  +         !isSet(analysis, BIT_FILTER))
  +      {
  +        if (DEBUG_ITERATOR_CREATION)
  +          diagnoseIterator("MatchPatternIterator", analysis, compiler);
  +
  +        return new MatchPatternIterator(compiler, opPos, analysis);
  +      }
  +      else
         {
           if (false || DEBUG_ITERATOR_CREATION)
           {
  -          System.out.println("new iterator:  LocPathIterator: "
  -                             + Integer.toBinaryString(analysis) + ", "
  -                             + compiler.toString());
  -          System.out.println("   "+getAnalysisString(analysis));
  +          diagnoseIterator("WalkingIterator", analysis, compiler);
           }
     
  -        return new LocPathIterator(compiler, opPos, analysis, true);
  +        return new WalkingIterator(compiler, opPos, analysis, true);
         }
  -      else
  -      {        
  -        if (DEBUG_ITERATOR_CREATION)
  -          System.out.println("new iterator:  MatchPatternIterator: " 
  -                            + Integer.toBinaryString(analysis) + ", "
  -                             + compiler.toString());
  +    }
  +  }
  +  
  +  /**
  +   * Special purpose function to see if we can optimize the pattern for 
  +   * a DescendantIterator.
  +   *
  +   * @param compiler non-null reference to compiler object that has processed
  +   *                 the XPath operations into an opcode map.
  +   * @param stepOpCodePos The opcode position for the step.
  +   * @param stepIndex The top-level step index withing the iterator.
  +   *
  +   * @return 32 bits as an integer that give information about the location
  +   * path as a whole.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public static int getAxisFromStep(
  +          Compiler compiler, int stepOpCodePos)
  +            throws javax.xml.transform.TransformerException
  +  {
   
  -        return new MatchPatternIterator(compiler, opPos, analysis);
  +    int ops[] = compiler.getOpMap();
  +    int stepType = ops[stepOpCodePos];
  +
  +    switch (stepType)
  +    {
  +    case OpCodes.FROM_FOLLOWING :
  +      return Axis.FOLLOWING;
  +    case OpCodes.FROM_FOLLOWING_SIBLINGS :
  +      return Axis.FOLLOWINGSIBLING;
  +    case OpCodes.FROM_PRECEDING :
  +      return Axis.PRECEDING;
  +    case OpCodes.FROM_PRECEDING_SIBLINGS :
  +      return Axis.PRECEDINGSIBLING;
  +    case OpCodes.FROM_PARENT :
  +      return Axis.PARENT;
  +    case OpCodes.FROM_NAMESPACE :
  +      return Axis.NAMESPACE;
  +    case OpCodes.FROM_ANCESTORS :
  +      return Axis.ANCESTOR;
  +    case OpCodes.FROM_ANCESTORS_OR_SELF :
  +      return Axis.ANCESTORORSELF;
  +    case OpCodes.FROM_ATTRIBUTES :
  +      return Axis.ATTRIBUTE;
  +    case OpCodes.FROM_ROOT :
  +      return Axis.ROOT;
  +    case OpCodes.FROM_CHILDREN :
  +      return Axis.CHILD;
  +    case OpCodes.FROM_DESCENDANTS_OR_SELF :
  +      return Axis.DESCENDANTORSELF;
  +    case OpCodes.FROM_DESCENDANTS :
  +      return Axis.DESCENDANT;
  +    case OpCodes.FROM_SELF :
  +      return Axis.SELF;
  +    case OpCodes.OP_EXTFUNCTION :
  +    case OpCodes.OP_FUNCTION :
  +    case OpCodes.OP_GROUP :
  +    case OpCodes.OP_VARIABLE :
  +      return Axis.FILTEREDLIST;
  +    }
  +
  +    throw new RuntimeException("Programmer's assertion: unknown opcode: "
  +                               + stepType);
  +  }
  +  
  +  static boolean functionProximateOrContainsProximate(Compiler compiler, 
  +                                                      int opPos)
  +  {
  +    int endFunc = opPos + compiler.getOp(opPos + 1) - 1;
  +    opPos = compiler.getFirstChildPos(opPos);
  +    int funcID = compiler.getOp(opPos);
  +    //  System.out.println("funcID: "+funcID);
  +    //  System.out.println("opPos: "+opPos);
  +    //  System.out.println("endFunc: "+endFunc);
  +    switch(funcID)
  +    {
  +      case FunctionTable.FUNC_LAST:
  +      case FunctionTable.FUNC_POSITION:
  +        return true;
  +      default:
  +        opPos++;
  +        int i = 0;
  +        for (int p = opPos; p < endFunc; p = compiler.getNextOpPos(p), i++)
  +        {
  +          int innerExprOpPos = p+2;
  +          int argOp = compiler.getOp(innerExprOpPos);
  +          boolean prox = isProximateInnerExpr(compiler, innerExprOpPos);
  +          if(prox)
  +            return true;
  +        }
  +
  +    }
  +    return false;
  +  }
  +  
  +  static boolean isProximateInnerExpr(Compiler compiler, int opPos)
  +  {
  +    int op = compiler.getOp(opPos);
  +    int innerExprOpPos = opPos+2;
  +    switch(op)
  +    {
  +      case OpCodes.OP_ARGUMENT:
  +        if(isProximateInnerExpr(compiler, innerExprOpPos))
  +          return true;
  +        break;
  +      case OpCodes.OP_VARIABLE:
  +      case OpCodes.OP_NUMBERLIT:
  +      case OpCodes.OP_LITERAL:
  +      case OpCodes.OP_LOCATIONPATH:
  +        break; // OK
  +      case OpCodes.OP_FUNCTION:
  +        boolean isProx 
  +          = functionProximateOrContainsProximate(compiler, op);
  +        if(isProx)
  +          return true;
  +        break;
  +      case OpCodes.OP_GT:
  +      case OpCodes.OP_GTE:
  +      case OpCodes.OP_LT:
  +      case OpCodes.OP_LTE:
  +      case OpCodes.OP_EQUALS:
  +        int leftPos = compiler.getFirstChildPos(op);
  +        int rightPos = compiler.getNextOpPos(leftPos);
  +        isProx = isProximateInnerExpr(compiler, leftPos);
  +        if(isProx)
  +          return true;
  +        isProx = isProximateInnerExpr(compiler, rightPos);
  +        if(isProx)
  +          return true;
  +        break;
  +      default:
  +        return true; // be conservative...
  +    }
  +    return false;
  +  }
  +    
  +  /**
  +   * Tell if the predicates need to have proximity knowledge.
  +   */
  +  static boolean mightBeProximate(Compiler compiler, int opPos, int stepType)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    boolean mightBeProximate = false;
  +    int argLen;
  +
  +    switch (stepType)
  +    {
  +    case OpCodes.OP_VARIABLE :
  +    case OpCodes.OP_EXTFUNCTION :
  +    case OpCodes.OP_FUNCTION :
  +    case OpCodes.OP_GROUP :
  +      argLen = compiler.getArgLength(opPos);
  +      break;
  +    default :
  +      argLen = compiler.getArgLengthOfStep(opPos);
  +    }
  +
  +    int predPos = compiler.getFirstPredicateOpPos(opPos);
  +    int count = 0;
  +
  +    while (OpCodes.OP_PREDICATE == compiler.getOp(predPos))
  +    {
  +      count++;
  +      
  +      int innerExprOpPos = predPos+2;
  +      int predOp = compiler.getOp(innerExprOpPos);
  +
  +      switch(predOp)
  +      {
  +        case OpCodes.OP_VARIABLE:
  +        case OpCodes.OP_LOCATIONPATH:
  +          // OK.
  +          break;
  +        case OpCodes.OP_NUMBER:
  +        case OpCodes.OP_NUMBERLIT:
  +          return true; // that's all she wrote!
  +        case OpCodes.OP_FUNCTION:
  +          boolean isProx 
  +            = functionProximateOrContainsProximate(compiler, innerExprOpPos);
  +          if(isProx)
  +            return true;
  +          break;
  +        case OpCodes.OP_GT:
  +        case OpCodes.OP_GTE:
  +        case OpCodes.OP_LT:
  +        case OpCodes.OP_LTE:
  +        case OpCodes.OP_EQUALS:
  +          int leftPos = compiler.getFirstChildPos(innerExprOpPos);
  +          int rightPos = compiler.getNextOpPos(leftPos);
  +          isProx = isProximateInnerExpr(compiler, leftPos);
  +          if(isProx)
  +            return true;
  +          isProx = isProximateInnerExpr(compiler, rightPos);
  +          if(isProx)
  +            return true;
  +          break;
  +        default:
  +          return true; // be conservative...
  +      }
  +
  +      predPos = compiler.getNextOpPos(predPos);
  +    }
  +
  +    return mightBeProximate;
  +  }
  +  
  +  /**
  +   * Special purpose function to see if we can optimize the pattern for 
  +   * a DescendantIterator.
  +   *
  +   * @param compiler non-null reference to compiler object that has processed
  +   *                 the XPath operations into an opcode map.
  +   * @param stepOpCodePos The opcode position for the step.
  +   * @param stepIndex The top-level step index withing the iterator.
  +   *
  +   * @return 32 bits as an integer that give information about the location
  +   * path as a whole.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  private static boolean isOptimizableForDescendantIterator(
  +          Compiler compiler, int stepOpCodePos, int stepIndex)
  +            throws javax.xml.transform.TransformerException
  +  {
  +
  +    int stepType;
  +    int ops[] = compiler.getOpMap();
  +    int stepCount = 0;
  +    boolean foundDorDS = false;
  +    boolean foundSelf = false;
  +    boolean foundDS = false;
  +    
  +    while (OpCodes.ENDOP != (stepType = ops[stepOpCodePos]))
  +    {
  +      stepCount++;
  +      if(stepCount > 3)
  +        return false;
  +        
  +      boolean mightBeProximate = mightBeProximate(compiler, stepOpCodePos, 
stepType);
  +      if(mightBeProximate)
  +        return false;
  +
  +      switch (stepType)
  +      {
  +      case OpCodes.FROM_FOLLOWING :
  +      case OpCodes.FROM_FOLLOWING_SIBLINGS :
  +      case OpCodes.FROM_PRECEDING :
  +      case OpCodes.FROM_PRECEDING_SIBLINGS :
  +      case OpCodes.FROM_PARENT :
  +      case OpCodes.OP_VARIABLE :
  +      case OpCodes.OP_EXTFUNCTION :
  +      case OpCodes.OP_FUNCTION :
  +      case OpCodes.OP_GROUP :
  +      case OpCodes.FROM_NAMESPACE :
  +      case OpCodes.FROM_ANCESTORS :
  +      case OpCodes.FROM_ANCESTORS_OR_SELF :
  +      case OpCodes.FROM_ATTRIBUTES :
  +      case OpCodes.MATCH_ATTRIBUTE :
  +      case OpCodes.MATCH_ANY_ANCESTOR :
  +      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
  +        return false;
  +      case OpCodes.FROM_ROOT :
  +        if(1 != stepCount)
  +          return false;
  +        break;
  +      case OpCodes.FROM_CHILDREN :
  +        if(!foundDS && !(foundDorDS && foundSelf))
  +          return false;
  +        break;
  +      case OpCodes.FROM_DESCENDANTS_OR_SELF :
  +        foundDS = true;
  +      case OpCodes.FROM_DESCENDANTS :
  +        if(3 == stepCount)
  +          return false;
  +        foundDorDS = true;
  +        break;
  +      case OpCodes.FROM_SELF :
  +        if(1 != stepCount)
  +          return false;
  +        foundSelf = true;
  +        break;
  +      default :
  +        throw new RuntimeException("Programmer's assertion: unknown opcode: "
  +                                   + stepType);
         }
  +
  +      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
  +
  +      if (stepOpCodePos < 0)
  +        break;
       }
  +
  +    return true;
     }
   
     /**
  @@ -825,7 +1125,7 @@
      * @throws RuntimeException if the input is bad.
      */
     private static AxesWalker createDefaultWalker(Compiler compiler, int opPos,
  -          LocPathIterator lpi, int analysis)
  +          WalkingIterator lpi, int analysis)
     {
   
       AxesWalker ai;
  @@ -1096,6 +1396,11 @@
     public static String getAnalysisString(int analysis)
     {
       StringBuffer buf = new StringBuffer();
  +    buf.append("count: "+getStepCount(analysis)+" ");
  +    if((analysis & BIT_NODETEST_ANY) != 0)
  +    {
  +      buf.append("NTANY|");
  +    }
       if((analysis & BIT_PREDICATE) != 0)
       {
         buf.append("PRED|");
  @@ -1171,6 +1476,223 @@
   
     /** Set to true for diagnostics about iterator creation */
     static final boolean DEBUG_ITERATOR_CREATION = false;
  +  
  +  public static boolean hasPredicate(int analysis)
  +  {
  +    return (0 != (analysis & BIT_PREDICATE));
  +  }
  +
  +  public static boolean isWild(int analysis)
  +  {
  +    return (0 != (analysis & BIT_NODETEST_ANY));
  +  }
  +
  +  public static boolean walksAncestors(int analysis)
  +  {
  +    return isSet(analysis, BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
  +  }
  +  
  +  public static boolean walksAttributes(int analysis)
  +  {
  +    return (0 != (analysis & BIT_ATTRIBUTE));
  +  }
  +
  +  public static boolean walksNamespaces(int analysis)
  +  {
  +    return (0 != (analysis & BIT_NAMESPACE));
  +  }
  +
  +  public static boolean walksChildren(int analysis)
  +  {
  +    return (0 != (analysis & BIT_CHILD));
  +  }
  +
  +  public static boolean walksDescendants(int analysis)
  +  {
  +    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF);
  +  }
  +
  +  public static boolean walksSubtree(int analysis)
  +  {
  +    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF | 
BIT_CHILD);
  +  }
  +  
  +  public static boolean walksSubtreeOnly(int analysis)
  +  {
  +    return walksSubtree(analysis)
  +           && !walksExtraNodes(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +
  +  public static boolean walksFilteredList(int analysis)
  +  {
  +    return isSet(analysis, BIT_FILTER);
  +  }
  +  
  +  public static boolean walksSubtreeOnlyFromRootOrContext(int analysis)
  +  {
  +    return walksSubtree(analysis)
  +           && !walksExtraNodes(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isSet(analysis, BIT_FILTER) 
  +           ;
  +  }
  +
  +  public static boolean walksInDocOrder(int analysis)
  +  {
  +    return (walksSubtree(analysis)
  +           || walksExtraNodes(analysis)
  +           || isSet(analysis, BIT_SELF | BIT_FOLLOWING_SIBLING | 
BIT_FOLLOWING)) 
  +           && !walksUp(analysis) 
  +           && !isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING) 
  +           && !isSet(analysis, BIT_FILTER) 
  +           ;
  +  }
  +  
  +  public static boolean walksUp(int analysis)
  +  {
  +    return isSet(analysis, BIT_PARENT | BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
  +  }
  +  
  +  public static boolean walksSideways(int analysis)
  +  {
  +    return isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING | 
  +                           BIT_PRECEDING | BIT_PRECEDING_SIBLING);
  +  }
  +  
  +  public static boolean walksExtraNodes(int analysis)
  +  {
  +    return isSet(analysis, BIT_NAMESPACE | BIT_ATTRIBUTE);
  +  }
  +
  +  public static boolean walksExtraNodesOnly(int analysis)
  +  {
  +    return walksExtraNodes(analysis)
  +           && !isSet(analysis, BIT_SELF) 
  +           && !walksSubtree(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +
  +  public static boolean isAbsolute(int analysis)
  +  {
  +    return isSet(analysis, BIT_ROOT | BIT_FILTER);
  +  }
  +  
  +  public static boolean walksChildrenOnly(int analysis)
  +  {
  +    return walksChildren(analysis)
  +           && !isSet(analysis, BIT_SELF)
  +           && !walksExtraNodes(analysis)
  +           && !walksDescendants(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +  
  +  public static boolean walksChildrenAndExtraAndSelfOnly(int analysis)
  +  {
  +    return walksChildren(analysis)
  +           && !walksDescendants(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +  
  +  public static boolean walksDescendantsAndExtraAndSelfOnly(int analysis)
  +  {
  +    return !walksChildren(analysis)
  +           && walksDescendants(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +  
  +  public static boolean walksSelfOnly(int analysis)
  +  {
  +    return isSet(analysis, BIT_SELF) 
  +           && !walksSubtree(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +
  +  
  +  public static boolean walksUpOnly(int analysis)
  +  {
  +    return !walksSubtree(analysis) 
  +           && walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +  
  +  public static boolean walksDownOnly(int analysis)
  +  {
  +    return walksSubtree(analysis) 
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +
  +  public static boolean walksDownExtraOnly(int analysis)
  +  {
  +    return walksSubtree(analysis) &&  walksExtraNodes(analysis)
  +           && !walksUp(analysis) 
  +           && !walksSideways(analysis) 
  +           && !isAbsolute(analysis) 
  +           ;
  +  }
  +  
  +  public static boolean canSkipSubtrees(int analysis)
  +  {
  +    return isSet(analysis, BIT_CHILD) | walksSideways(analysis);
  +  }
  +  
  +  public static boolean canCrissCross(int analysis)
  +  {
  +    // This could be done faster.  Coded for clarity.
  +    if(walksSelfOnly(analysis))
  +      return false;
  +    else if(walksDownOnly(analysis) && !canSkipSubtrees(analysis))
  +      return false;
  +    else if(walksChildrenAndExtraAndSelfOnly(analysis))
  +      return false;
  +    else if(walksDescendantsAndExtraAndSelfOnly(analysis))
  +      return false;
  +    else if(walksUpOnly(analysis))
  +      return false;
  +    else if(walksExtraNodesOnly(analysis))
  +      return false;
  +    else if(walksSubtree(analysis) 
  +           && (walksSideways(analysis) 
  +            || walksUp(analysis) 
  +            || canSkipSubtrees(analysis)))
  +      return true;
  +    else
  +      return false;
  +  }
  +  
  +  public static boolean isOneStep(int analysis)
  +  {
  +    return (analysis & BITS_COUNT) == 0x00000001;
  +  }
  +
  +  public static int getStepCount(int analysis)
  +  {
  +    return (analysis & BITS_COUNT);
  +  }
   
     /**
      * First 8 bits are the number of top-level location steps.  Hopefully
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1   +222 -0    
xml-xalan/java/src/org/apache/xpath/axes/Attic/OneStepIterator.java
  
  
  
  
  1.1.2.1   +77 -0     
xml-xalan/java/src/org/apache/xpath/axes/Attic/OneStepIteratorForward.java
  
  
  
  
  1.1.2.1   +92 -0     
xml-xalan/java/src/org/apache/xpath/axes/Attic/SelfIteratorNoPredicate.java
  
  
  
  
  1.1.2.1   +228 -0    
xml-xalan/java/src/org/apache/xpath/axes/Attic/WalkingIterator.java
  
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.5.2.2   +3 -1      
xml-xalan/java/src/org/apache/xpath/functions/FuncLocalPart.java
  
  Index: FuncLocalPart.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncLocalPart.java,v
  retrieving revision 1.5.2.1
  retrieving revision 1.5.2.2
  diff -u -r1.5.2.1 -r1.5.2.2
  --- FuncLocalPart.java        2001/04/10 18:45:30     1.5.2.1
  +++ FuncLocalPart.java        2001/05/27 02:28:53     1.5.2.2
  @@ -89,10 +89,12 @@
     {
   
       int context = getArg0AsNode(xctxt);
  +    if(DTM.NULL == context)
  +      return XString.EMPTYSTRING;
       DTM dtm = xctxt.getDTM(context);
       String s = (context != DTM.NULL) ? dtm.getLocalName(context) : "";
       if(s.startsWith("#") || s.equals("xmlns"))
  -      s = "";
  +      return XString.EMPTYSTRING;
   
       return new XString(s);
     }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to