sboag       01/05/21 04:44:06

  Modified:    java/src/org/apache/xml/dtm Tag: DTM_EXP Axis.java DTM.java
                        DTMDefaultBase.java DTMDocumentImpl.java
  Log:
  Introduction of stateless AxisTraversers, for polymorphic axis traversal,
  mainly for match patterns/match iterators.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +46 -22    xml-xalan/java/src/org/apache/xml/dtm/Attic/Axis.java
  
  Index: Axis.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/Axis.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- Axis.java 2001/05/20 17:33:26     1.1.2.1
  +++ Axis.java 2001/05/21 11:43:59     1.1.2.2
  @@ -69,20 +69,20 @@
      * The ancestor axis contains the ancestors of the context node;
      *  the ancestors of the context node consist of the parent of context
      *  node and the parent's parent and so on; thus, the ancestor axis will
  -   *  always include the root node, unless the context node is the root 
node. 
  +   *  always include the root node, unless the context node is the root node.
      */
     public static final int ANCESTOR = 0;
   
     /**
      * the ancestor-or-self axis contains the context node and the ancestors of
      *  the context node; thus, the ancestor axis will always include the
  -   *  root node. 
  +   *  root node.
      */
     public static final int ANCESTORORSELF = 1;
   
     /**
      * the attribute axis contains the attributes of the context node; the axis
  -   *  will be empty unless the context node is an element.  
  +   *  will be empty unless the context node is an element.
      */
     public static final int ATTRIBUTE = 2;
   
  @@ -92,64 +92,88 @@
     /**
      * The descendant axis contains the descendants of the context node;
      *  a descendant is a child or a child of a child and so on; thus the
  -   *  descendant axis never contains attribute or namespace nodes.         
  +   *  descendant axis never contains attribute or namespace nodes.
      */
     public static final int DESCENDANT = 4;
   
     /**
      * The descendant-or-self axis contains the context node and the
  -   *  descendants of the context node.  
  +   *  descendants of the context node.
      */
     public static final int DESCENDANTORSELF = 5;
   
     /**
      * the following axis contains all nodes in the same document as the
      *  context node that are after the context node in document order, 
excluding
  -   *  any descendants and excluding attribute nodes and namespace nodes. 
  +   *  any descendants and excluding attribute nodes and namespace nodes.
      */
     public static final int FOLLOWING = 6;
   
     /**
      * The following-sibling axis contains all the following siblings of the
      *  context node; if the context node is an attribute node or namespace 
node,
  -   *  the following-sibling axis is empty. 
  +   *  the following-sibling axis is empty.
      */
     public static final int FOLLOWINGSIBLING = 7;
   
     /**
      * The namespace axis contains the namespace nodes of the context node; the
  -   *  axis will be empty unless the context node is an element.  
  +   *  axis will be empty unless the context node is an element.
      */
  -  public static final int NAMESPACE = 8;
  +  public static final int NAMESPACEDECLS = 8;
   
     /**
  +   * The namespace axis contains the namespace nodes of the context node; the
  +   *  axis will be empty unless the context node is an element.
  +   */
  +  public static final int NAMESPACE = 9;
  +
  +  /**
      * The parent axis contains the parent of the context node,
  -   *  if there is one.  
  +   *  if there is one.
      */
  -  public static final int PARENT = 9;
  +  public static final int PARENT = 10;
   
     /**
      * The preceding axis contains all nodes in the same document as the 
context
      *  node that are before the context node in document order, excluding any
  -   *  ancestors and excluding attribute nodes and namespace nodes 
  +   *  ancestors and excluding attribute nodes and namespace nodes
      */
  -  public static final int PRECEDING = 10;
  +  public static final int PRECEDING = 11;
   
     /**
      * The preceding-sibling axis contains all the preceding siblings of the
      *  context node; if the context node is an attribute node or namespace 
node,
  -   *  the preceding-sibling axis is empty.  
  +   *  the preceding-sibling axis is empty.
      */
  -  public static final int PRECEDINGSIBLING = 11;
  +  public static final int PRECEDINGSIBLING = 12;
   
     /** The self axis contains just the context node itself. */
  -  public static final int SELF = 12;
  +  public static final int SELF = 13;
  +
  +  /**
  +   * A non-xpath axis, traversing the subtree including the subtree
  +   *  root, descendants, attributes, and namespace node decls.
  +   */
  +  public static final int SUBTREE = 14;
   
     /** The names of the axes for diagnostic purposes. */
  -  public static final String[] names = { "ancestor", "ancestor-or-self",
  -                                         "attribute", "child", "descendant",
  -                                         "descendant-or-self", "following",
  -                                         "following-sibling", "namespace",
  -                                         "parent", "preceding",
  -                                         "preceding-sibling", "self" };
  +  public static final String[] names =
  +  {
  +    "ancestor",  // 0
  +    "ancestor-or-self",  // 1
  +    "attribute",  // 2
  +    "child",  // 3
  +    "descendant",  // 4
  +    "descendant-or-self",  // 5
  +    "following",  // 6
  +    "following-sibling",  // 7
  +    "namespace-decls",  // 8
  +    "namespace",  // 9
  +    "parent",  // 10
  +    "preceding",  // 11
  +    "preceding-sibling",  // 12
  +    "self",  // 13
  +    "subtree"  // 14
  +  };
   }
  
  
  
  1.1.2.18  +12 -2     xml-xalan/java/src/org/apache/xml/dtm/Attic/DTM.java
  
  Index: DTM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTM.java,v
  retrieving revision 1.1.2.17
  retrieving revision 1.1.2.18
  diff -u -r1.1.2.17 -r1.1.2.18
  --- DTM.java  2001/05/20 17:33:26     1.1.2.17
  +++ DTM.java  2001/05/21 11:44:00     1.1.2.18
  @@ -189,8 +189,18 @@
     // ========= Document Navigation Functions =========
     
     /**
  -   * This is a shortcut to the iterators that implement the
  -   * supported XPath axes (only namespace::) is not supported.
  +   * This returns a stateless "traverser", that can navigate over an 
  +   * XPath axis, though not in document order.
  +   *
  +   * @param axis One of Axes.ANCESTORORSELF, etc.
  +   *
  +   * @return A DTMAxisIterator, or null if the givin axis isn't supported.
  +   */
  +  public DTMAxisTraverser getAxisTraverser(final int axis);
  +  
  +  /**
  +   * This is a shortcut to the iterators that implement 
  +   * XPath axes.
      * Returns a bare-bones iterator that must be initialized
      * with a start node (using iterator.setStartNode()).
      *
  
  
  
  1.1.2.9   +853 -1    
xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDefaultBase.java
  
  Index: DTMDefaultBase.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDefaultBase.java,v
  retrieving revision 1.1.2.8
  retrieving revision 1.1.2.9
  diff -u -r1.1.2.8 -r1.1.2.9
  --- DTMDefaultBase.java       2001/05/20 17:33:26     1.1.2.8
  +++ DTMDefaultBase.java       2001/05/21 11:44:01     1.1.2.9
  @@ -214,7 +214,11 @@
      * @return the number of nodes that have been mapped.
      */
     protected abstract int getNumberOfNodes();
  +  
  +  /** Stateless axis traversers, lazely built. */
  +  protected DTMAxisTraverser[] m_traversers;
   
  +
     /**
      * Ensure that the size of the information arrays can hold another entry
      * at the given index.
  @@ -1711,6 +1715,86 @@
       if (null != m_shouldStripWhitespaceStack)
         m_shouldStripWhitespaceStack.setTop(shouldStrip);
     }
  +  
  +  /**
  +   * This returns a stateless "traverser", that can navigate over an
  +   * XPath axis, though perhaps not in document order.
  +   *
  +   * @param axis One of Axes.ANCESTORORSELF, etc.
  +   *
  +   * @return A DTMAxisIterator, or null if the givin axis isn't supported.
  +   */
  +  public DTMAxisTraverser getAxisTraverser(final int axis)
  +  {
  +    DTMAxisTraverser traverser;
  +    if(null == m_traversers)
  +    {
  +      m_traversers = new DTMAxisTraverser[Axis.names.length];
  +      traverser = null;
  +    }
  +    else
  +    {
  +      traverser = m_traversers[axis];
  +      if(traverser != null)
  +        return traverser;
  +    }
  +      
  +    switch (axis) 
  +    {
  +      case Axis.ANCESTOR:
  +        traverser = new AncestorTraverser();
  +        break;
  +      case Axis.ANCESTORORSELF:
  +        traverser = new AncestorOrSelfTraverser();
  +        break;
  +      case Axis.ATTRIBUTE:
  +        traverser = new AttributeTraverser();
  +        break;
  +      case Axis.CHILD:
  +        traverser = new ChildTraverser();
  +        break;
  +      case Axis.DESCENDANT:
  +        traverser = new DescendantTraverser();
  +        break;
  +      case Axis.DESCENDANTORSELF:
  +        traverser = new DescendantTraverser();
  +        break;
  +      case Axis.FOLLOWING:
  +        traverser = new FollowingTraverser();
  +        break;
  +      case Axis.FOLLOWINGSIBLING:
  +        traverser = new FollowingSiblingTraverser();
  +        break;
  +      case Axis.NAMESPACE:
  +        traverser = new NamespaceTraverser();
  +        break;
  +      case Axis.NAMESPACEDECLS:
  +        traverser = new NamespaceDeclsTraverser();
  +        break;
  +      case Axis.PARENT:
  +        traverser = new ParentTraverser();
  +        break;
  +      case Axis.PRECEDING:
  +        traverser = new PrecedingTraverser();
  +        break;
  +      case Axis.PRECEDINGSIBLING:
  +        traverser = new PrecedingSiblingTraverser();
  +        break;
  +      case Axis.SELF:
  +        traverser = new SelfTraverser();
  +        break;
  +      case Axis.SUBTREE:
  +        traverser = new SubtreeTraverser();
  +        break;
  +      default:
  +        throw new DTMException("Unknown axis traversal type");
  +    }
  +    if(null == traverser)
  +      throw new DTMException("Axis traverser not supported: 
"+Axis.names[axis]);
  +      
  +    m_traversers[axis] = traverser;
  +    return traverser;
  +  }
   
     /**
      * Get an iterator that can navigate over an XPath Axis, predicated by
  @@ -1785,7 +1869,7 @@
   
     /**
      * This is a shortcut to the iterators that implement the
  -   * supported XPath axes (only namespace::) is not supported.
  +   * XPath axes.
      * Returns a bare-bones iterator that must be initialized
      * with a start node (using iterator.setStartNode()).
      *
  @@ -3490,4 +3574,772 @@
         return getExpandedTypeID(result) == _nodeType ? result : NULL;
       }
     }  // end of TypedSingletonIterator
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class AncestorTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return m_parent[current & m_mask] | m_dtmIdent;
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      current = current & m_mask;
  +
  +      while (DTM.NULL != (current = m_parent[current]))
  +      {
  +        if (m_exptype[current] == extendedTypeID)
  +          return current | m_dtmIdent;
  +      }
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class AncestorOrSelfTraverser extends AncestorTraverser
  +  {
  +
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  To see if
  +     * the self node should be processed, use this function.
  +     *
  +     * @return true if the context node should be processed for this axis.
  +     */
  +    public boolean processSelf()
  +    {
  +      return true;
  +    }
  +
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  To see if
  +     * the self node should be processed, use this function.  If the context
  +     * node does not match the extended type ID, this function will return
  +     * false.
  +     *
  +     * @param context The context node if this traversal.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return true if the context node should be processed for this axis, 
and
  +     * the extendedTypeID matches that of the context.
  +     */
  +    public boolean processSelf(int context, int extendedTypeID)
  +    {
  +      return (m_exptype[context & m_mask] == extendedTypeID);
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class AttributeTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return (context == current)
  +             ? getFirstAttribute(context) : getNextAttribute(current);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      current = (context == current)
  +                ? getFirstAttribute(context) : getNextAttribute(current);
  +
  +      do
  +      {
  +        if (m_exptype[current] == extendedTypeID)
  +          return current;
  +      }
  +      while (DTM.NULL != (current = getNextAttribute(current)));
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class ChildTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      // %OPT%
  +      return (context == current)
  +             ? getFirstChild(context) : getNextSibling(current);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      current = (context == current)
  +                ? getFirstChild(context) : getNextSibling(current);
  +
  +      do
  +      {
  +        if (m_exptype[current & m_mask] == extendedTypeID)
  +          return current;
  +      }
  +      while (DTM.NULL != (current = getNextSibling(current)));
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class DescendantTraverser extends DTMAxisTraverser
  +  {
  +    
  +    /**
  +     * Tell if this node identity is a descendant.  Assumes that
  +     * the node info for the element has already been obtained.
  +     * @param identity The index number of the node in question.
  +     * @return true if the index is a descendant of _startNode.
  +     */
  +    protected boolean isDescendant(int subtreeRootIdentity, int identity)
  +    {
  +      return _parent(identity) >= subtreeRootIdentity;
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      int subtreeRootIdent = context & m_mask;
  +      
  +      for (current = (current & m_mask)+1;;current++)
  +      {
  +        int type = _type(current); // may call nextNode()
  +
  +        if (!isDescendant(subtreeRootIdent, current))
  +          return NULL;
  +
  +        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
  +          continue;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      int subtreeRootIdent = context & m_mask;
  +      
  +      for (current = (current & m_mask)+1;;current++)
  +      {
  +        int exptype = _exptype(current); // may call nextNode()
  +
  +        if (!isDescendant(subtreeRootIdent, current))
  +          return NULL;
  +
  +        if (exptype != extendedTypeID)
  +          continue;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class DescendantOrSelfTraverser extends DescendantTraverser
  +  {
  +
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  To see if
  +     * the self node should be processed, use this function.
  +     *
  +     * @return true if the context node should be processed for this axis.
  +     */
  +    public boolean processSelf()
  +    {
  +      return true;
  +    }
  +
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  To see if
  +     * the self node should be processed, use this function.  If the context
  +     * node does not match the extended type ID, this function will return
  +     * false.
  +     *
  +     * @param context The context node if this traversal.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return true if the context node should be processed for this axis, 
and
  +     * the extendedTypeID matches that of the context.
  +     */
  +    public boolean processSelf(int context, int extendedTypeID)
  +    {
  +      return (m_exptype[context & m_mask] == extendedTypeID);
  +    }
  +  }
  +  
  +  /**
  +   * Implements traversal of the entire subtree, including the root node.
  +   */
  +  private class SubtreeTraverser extends DescendantOrSelfTraverser
  +  {
  +    
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      int subtreeRootIdent = context & m_mask;
  +      
  +      for (current = (current & m_mask)+1;;current++)
  +      {
  +        _exptype(current); // make sure it's here.
  +
  +        if (!isDescendant(subtreeRootIdent, current))
  +          return NULL;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +    }
  +
  +  }
  +
  +
  +  /**
  +   * Implements traversal of the following access, in document order.
  +   */
  +  private class FollowingTraverser extends DescendantTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    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++)
  +      {
  +        int type = _type(current); // may call nextNode()
  +
  +        if(NULL == type)
  +          return NULL;
  +
  +        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
  +          continue;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    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++)
  +      {
  +        int exptype = _exptype(current); // may call nextNode()
  +        
  +        if(NULL == exptype)
  +          return NULL;
  +
  +        if (exptype != extendedTypeID)
  +          continue;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class FollowingSiblingTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return getNextSibling(current);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      while (DTM.NULL != (current = getNextSibling(current)))
  +      {
  +        if (m_exptype[current & m_mask] == extendedTypeID)
  +          return current;
  +      }
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class NamespaceDeclsTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return (context == current)
  +             ? getFirstNamespaceNode(context, false) 
  +             : getNextNamespaceNode(context, current, false);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      current = (context == current)
  +                ? getFirstNamespaceNode(context, false) 
  +                : getNextNamespaceNode(context, current, false);
  +
  +      do
  +      {
  +        if (m_exptype[current] == extendedTypeID)
  +          return current;
  +      }
  +      while (DTM.NULL != (current = getNextNamespaceNode(context, current, 
false)));
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class NamespaceTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return (context == current)
  +             ? getFirstNamespaceNode(context, true) 
  +             : getNextNamespaceNode(context, current, true);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      current = (context == current)
  +                ? getFirstNamespaceNode(context, true) 
  +                : getNextNamespaceNode(context, current, true);
  +
  +      do
  +      {
  +        if (m_exptype[current] == extendedTypeID)
  +          return current;
  +      }
  +      while (DTM.NULL != (current = getNextNamespaceNode(context, current, 
true)));
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class ParentTraverser extends DTMAxisTraverser
  +  {
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      if(context == current)
  +        return m_parent[current & m_mask] | m_dtmIdent;
  +      else
  +        return NULL;
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +      if(context != current)
  +        return NULL;
  +
  +      current = current & m_mask;
  +
  +      while (NULL != (current = m_parent[current]))
  +      {
  +        if (m_exptype[current] == extendedTypeID)
  +          return (current | m_dtmIdent);
  +      }
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class PrecedingTraverser extends DTMAxisTraverser
  +  {
  +    /**
  +     * Tell if the current identity is an ancestor of the context identity.
  +     * This is an expensive operation, made worse by the stateless traversal.
  +     * But the preceding axis is used fairly infrequently.
  +     * 
  +     * @param contextIdent The context node of the axis traversal.
  +     * @param currentIdent The node in question.
  +     * @return true if the currentIdent node is an ancestor of contextIdent.
  +     */
  +    protected boolean isAncestor(int contextIdent, int currentIdent)
  +    {
  +      for (contextIdent = m_parent[contextIdent]; 
  +           DTM.NULL != contextIdent; 
  +           contextIdent = m_parent[contextIdent]) 
  +      {
  +        if(contextIdent == currentIdent)
  +          return true;
  +      }
  +      return false;
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      int subtreeRootIdent = context & m_mask;
  +      
  +      for (current = (current & m_mask)-1;current >= 0;current--)
  +      {
  +        int exptype = m_exptype[current];
  +        int type = ExpandedNameTable.getType(exptype);
  +
  +        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type ||
  +            isAncestor(subtreeRootIdent, current))
  +          continue;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +      return NULL;
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      int subtreeRootIdent = context & m_mask;
  +      
  +      for (current = (current & m_mask)-1;current >= 0;current--)
  +      {
  +        int exptype = m_exptype[current];
  +        int type = ExpandedNameTable.getType(exptype);
  +
  +        if (exptype != extendedTypeID ||
  +            isAncestor(subtreeRootIdent, current))
  +          continue;
  +
  +        return (current | m_dtmIdent);  // make handle.
  +      }
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Ancestor access, in reverse document order.
  +   */
  +  private class PrecedingSiblingTraverser extends DTMAxisTraverser
  +  {
  +
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return getPreviousSibling(current);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +
  +      while (DTM.NULL != (current = getPreviousSibling(current)))
  +      {
  +        if (m_exptype[current & m_mask] == extendedTypeID)
  +          return current;
  +      }
  +
  +      return NULL;
  +    }
  +  }
  +
  +  /**
  +   * Implements traversal of the Self axis.
  +   */
  +  private class SelfTraverser extends DTMAxisTraverser
  +  {
  +
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  To see if
  +     * the self node should be processed, use this function.
  +     *
  +     * @return true if the context node should be processed for this axis.
  +     */
  +    public boolean processSelf()
  +    {
  +      return true;
  +    }
  +
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  To see if
  +     * the self node should be processed, use this function.  If the context
  +     * node does not match the extended type ID, this function will return
  +     * false.
  +     *
  +     * @param context The context node if this traversal.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return true if the context node should be processed for this axis, 
and
  +     * the extendedTypeID matches that of the context.
  +     */
  +    public boolean processSelf(int context, int extendedTypeID)
  +    {
  +      return (m_exptype[context & m_mask] == extendedTypeID);
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     *
  +     * @return Always return NULL for this axis.
  +     */
  +    public int next(int context, int current)
  +    {
  +      return NULL;
  +    }
  +
  +    /**
  +     * Traverse to the next node after the current node that is matched
  +     * by the extended type ID.
  +     *
  +     * @param context The context node if this iteration.
  +     * @param current The current node of the iteration.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the next node in the iteration, or DTM.NULL.
  +     */
  +    public int next(int context, int current, int extendedTypeID)
  +    {
  +      return NULL;
  +    }
  +  }
   }
  
  
  
  1.1.2.21  +13 -0     
xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDocumentImpl.java
  
  Index: DTMDocumentImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDocumentImpl.java,v
  retrieving revision 1.1.2.20
  retrieving revision 1.1.2.21
  diff -u -r1.1.2.20 -r1.1.2.21
  --- DTMDocumentImpl.java      2001/05/20 17:33:26     1.1.2.20
  +++ DTMDocumentImpl.java      2001/05/21 11:44:02     1.1.2.21
  @@ -2314,6 +2314,19 @@
     }
     
     /**
  +   * This returns a stateless "traverser", that can navigate over an 
  +   * XPath axis, though not in document order.
  +   *
  +   * @param axis One of Axes.ANCESTORORSELF, etc.
  +   *
  +   * @return A DTMAxisIterator, or null if the givin axis isn't supported.
  +   */
  +  public DTMAxisTraverser getAxisTraverser(final int axis)
  +  {
  +    return null;
  +  }
  +  
  +  /**
      * This is a shortcut to the iterators that implement the
      * supported XPath axes (only namespace::) is not supported.
      * Returns a bare-bones iterator that must be initialized
  
  
  

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

Reply via email to