19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: DTMDefaultBaseTraversers.java 468653 2006-10-28 07:07:05Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.dtm.ref;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.*;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.Source;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLStringFactory;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLErrorResources;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLMessages;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class implements the traversers for DTMDefaultBase.
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * PLEASE NOTE that the public interface for all traversers should be
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * in terms of DTM Node Handles... but they may use the internal node
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * identity indices within their logic, for efficiency's sake. Be very
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * careful to avoid confusing these when maintaining this code.
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic abstract class DTMDefaultBaseTraversers extends DTMDefaultBase
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a DTMDefaultBaseTraversers object from a DOM node.
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mgr The DTMManager who owns this DTM.
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param source The object that is used to specify the construction source.
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param dtmIdentity The DTM identity ID for this DTM.
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param whiteSpaceFilter The white space filter for this DTM, which may
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                         be null.
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xstringfactory The factory to use for creating XMLStrings.
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param doIndexing true if the caller considers it worth it to use
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                   indexing schemes.
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  int dtmIdentity,
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  DTMWSFilter whiteSpaceFilter,
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  XMLStringFactory xstringfactory,
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  boolean doIndexing)
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          doIndexing);
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a DTMDefaultBaseTraversers object from a DOM node.
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mgr The DTMManager who owns this DTM.
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param source The object that is used to specify the construction source.
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param dtmIdentity The DTM identity ID for this DTM.
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param whiteSpaceFilter The white space filter for this DTM, which may
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                         be null.
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xstringfactory The factory to use for creating XMLStrings.
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param doIndexing true if the caller considers it worth it to use
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                   indexing schemes.
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param blocksize The block size of the DTM.
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param usePrevsib true if we want to build the previous sibling node array.
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  int dtmIdentity,
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  DTMWSFilter whiteSpaceFilter,
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  XMLStringFactory xstringfactory,
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  boolean doIndexing,
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  int blocksize,
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  boolean usePrevsib,
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  boolean newNameTable)
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          doIndexing, blocksize, usePrevsib, newNameTable);
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This returns a stateless "traverser", that can navigate
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * over an XPath axis, though perhaps not in document order.
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param axis One of Axes.ANCESTORORSELF, etc.
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A DTMAxisTraverser, or null if the given axis isn't supported.
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMAxisTraverser getAxisTraverser(final int axis)
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTMAxisTraverser traverser;
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null == m_traversers)  // Cache of stateless traversers for this DTM
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_traversers = new DTMAxisTraverser[Axis.getNamesLength()];
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = null;
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = m_traversers[axis];  // Share/reuse existing traverser
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (traverser != null)
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return traverser;
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (axis)  // Generate new traverser
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.ANCESTOR :
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new AncestorTraverser();
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.ANCESTORORSELF :
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new AncestorOrSelfTraverser();
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.ATTRIBUTE :
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new AttributeTraverser();
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.CHILD :
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new ChildTraverser();
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.DESCENDANT :
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new DescendantTraverser();
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.DESCENDANTORSELF :
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new DescendantOrSelfTraverser();
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.FOLLOWING :
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new FollowingTraverser();
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.FOLLOWINGSIBLING :
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new FollowingSiblingTraverser();
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.NAMESPACE :
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new NamespaceTraverser();
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.NAMESPACEDECLS :
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new NamespaceDeclsTraverser();
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.PARENT :
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new ParentTraverser();
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.PRECEDING :
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new PrecedingTraverser();
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.PRECEDINGSIBLING :
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new PrecedingSiblingTraverser();
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.SELF :
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new SelfTraverser();
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.ALL :
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new AllFromRootTraverser();
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.ALLFROMNODE :
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new AllFromNodeTraverser();
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.PRECEDINGANDANCESTOR :
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new PrecedingAndAncestorTraverser();
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.DESCENDANTSFROMROOT :
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new DescendantFromRootTraverser();
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.DESCENDANTSORSELFFROMROOT :
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new DescendantOrSelfFromRootTraverser();
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.ROOT :
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      traverser = new RootTraverser();
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case Axis.FILTEREDLIST :
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return null; // Don't want to throw an exception for this one.
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_UNKNOWN_AXIS_TYPE, new Object[]{Integer.toString(axis)})); //"Unknown axis traversal type: "+axis);
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null == traverser)
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_AXIS_TRAVERSER_NOT_SUPPORTED, new Object[]{Axis.getNames(axis)}));
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // "Axis traverser not supported: "
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //                       + Axis.names[axis]);
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_traversers[axis] = traverser;
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return traverser;
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class AncestorTraverser extends DTMAxisTraverser
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node if this iteration.
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			return getParent(current);
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Process using identities
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      current = makeNodeIdentity(current);
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != (current = m_parent.elementAt(current)))
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_exptype.elementAt(current) == expandedTypeID)
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return makeNodeHandle(current);
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class AncestorOrSelfTraverser extends AncestorTraverser
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  To see if
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node should be processed, use this function.
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return context;
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  To see if
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node should be processed, use this function.  If the context
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * node does not match the expanded type ID, this function will return
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * false.
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			return (getExpandedTypeID(context) == expandedTypeID)
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             ? context : next(context, context, expandedTypeID);
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Attribute access
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class AttributeTraverser extends DTMAxisTraverser
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (context == current)
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             ? getFirstAttribute(context) : getNextAttribute(current);
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      current = (context == current)
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                ? getFirstAttribute(context) : getNextAttribute(current);
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (getExpandedTypeID(current) == expandedTypeID)
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return current;
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != (current = getNextAttribute(current)));
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class ChildTraverser extends DTMAxisTraverser
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next indexed node that matches the expanded type ID.  Before
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * calling this function, one should first call
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * {@link #isIndexed(int) isIndexed} to make sure that the index can
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * contain nodes that match the given expanded type ID.
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axisRoot The root identity of the axis.
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nextPotential The node found must match or occur after this node.
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID for the request.
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The node ID or NULL if not found.
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getNextIndexed(int axisRoot, int nextPotential,
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 int expandedTypeID)
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nsIndex = m_expandedNameTable.getNamespaceID(expandedTypeID);
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int lnIndex = m_expandedNameTable.getLocalNameID(expandedTypeID);
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (; ; )
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int nextID = findElementFromIndex(nsIndex, lnIndex, nextPotential);
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NOTPROCESSED != nextID)
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int parentID = m_parent.elementAt(nextID);
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Is it a child?
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(parentID == axisRoot)
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return nextID;
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // If the parent occured before the subtree root, then
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // we know it is past the child axis.
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(parentID < axisRoot)
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              return NULL;
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Otherwise, it could be a descendant below the subtree root
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // children, or it could be after the subtree root.  So we have
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // to climb up until the parent is less than the subtree root, in
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // which case we return NULL, or until it is equal to the subtree
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // root, in which case we continue to look.
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          do
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            parentID = m_parent.elementAt(parentID);
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if(parentID < axisRoot)
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              return NULL;
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while(parentID > axisRoot);
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // System.out.println("Found node via index: "+first);
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          nextPotential = nextID+1;
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nextNode();
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(!(m_nextsib.elementAt(axisRoot) == NOTPROCESSED))
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return DTM.NULL;
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * that the traversal starts from.
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getFirstChild(context);
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of origin for the traversal -- its "root node" or starting point.
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(true)
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int identity = makeNodeIdentity(context);
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int firstMatch = getNextIndexed(identity, _firstch(identity),
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 expandedTypeID);
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(firstMatch);
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson				// %REVIEW% Dead code. Eliminate?
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int current = _firstch(makeNodeIdentity(context));
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             DTM.NULL != current;
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             current = _nextsib(current))
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (m_exptype.elementAt(current) == expandedTypeID)
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              return makeNodeHandle(current);
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getNextSibling(current);
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Process in Identifier space
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = _nextsib(makeNodeIdentity(current));
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           DTM.NULL != current;
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           current = _nextsib(current))
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_exptype.elementAt(current) == expandedTypeID)
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return makeNodeHandle(current);
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Super class for derived classes that want a convenient way to access
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the indexing mechanism.
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private abstract class IndexedDTMAxisTraverser extends DTMAxisTraverser
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if the indexing is on and the given expanded type ID matches
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * what is in the indexes.  Derived classes should call this before
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * calling {@link #getNextIndexed(int, int, int) getNextIndexed} method.
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID being requested.
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if it is OK to call the
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *         {@link #getNextIndexed(int, int, int) getNextIndexed} method.
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final boolean isIndexed(int expandedTypeID)
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (m_indexing
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && ExpandedNameTable.ELEMENT
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 == m_expandedNameTable.getType(expandedTypeID));
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if a node is outside the axis being traversed.  This method must be
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * implemented by derived classes, and must be robust enough to handle any
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * node that occurs after the axis root.
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axisRoot The root identity of the axis.
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The node in question.
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the given node falls outside the axis being traversed.
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected abstract boolean isAfterAxis(int axisRoot, int identity);
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if the axis has been fully processed to tell if a the wait for
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an arriving node should terminate.  This method must be implemented
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * be a derived class.
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axisRoot The root identity of the axis.
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the axis has been fully processed.
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected abstract boolean axisHasBeenProcessed(int axisRoot);
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next indexed node that matches the expanded type ID.  Before
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * calling this function, one should first call
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * {@link #isIndexed(int) isIndexed} to make sure that the index can
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * contain nodes that match the given expanded type ID.
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axisRoot The root identity of the axis.
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nextPotential The node found must match or occur after this node.
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID for the request.
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The node ID or NULL if not found.
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getNextIndexed(int axisRoot, int nextPotential,
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 int expandedTypeID)
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nsIndex = m_expandedNameTable.getNamespaceID(expandedTypeID);
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int lnIndex = m_expandedNameTable.getLocalNameID(expandedTypeID);
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while(true)
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int next = findElementFromIndex(nsIndex, lnIndex, nextPotential);
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NOTPROCESSED != next)
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (isAfterAxis(axisRoot, next))
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return NULL;
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // System.out.println("Found node via index: "+first);
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return next;
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if(axisHasBeenProcessed(axisRoot))
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nextNode();
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return DTM.NULL;
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class DescendantTraverser extends IndexedDTMAxisTraverser
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first potential identity that can be returned.  This should
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * be overridded by classes that need to return the self node.
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The node identity of the root context of the traversal.
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The first potential node that can be in the traversal.
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getFirstPotential(int identity)
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return identity + 1;
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if the axis has been fully processed to tell if a the wait for
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an arriving node should terminate.
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axisRoot The root identity of the axis.
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the axis has been fully processed.
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean axisHasBeenProcessed(int axisRoot)
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return !(m_nextsib.elementAt(axisRoot) == NOTPROCESSED);
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the subtree root identity from the handle that was passed in by
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the caller.  Derived classes may override this to change the root
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * context of the traversal.
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handle handle to the root context.
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return identity of the root of the subtree.
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getSubtreeRoot(int handle)
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return makeNodeIdentity(handle);
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if this node identity is a descendant.  Assumes that
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the node info for the element has already been obtained.
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * %REVIEW% This is really parentFollowsRootInDocumentOrder ...
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * which fails if the parent starts after the root ends.
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * May be sufficient for this class's logic, but misleadingly named!
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param subtreeRootIdentity The root context of the subtree in question.
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The index number of the node in question.
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the index is a descendant of _startNode.
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean isDescendant(int subtreeRootIdentity, int identity)
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return _parent(identity) >= subtreeRootIdentity;
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if a node is outside the axis being traversed.  This method must be
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * implemented by derived classes, and must be robust enough to handle any
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * node that occurs after the axis root.
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axisRoot The root identity of the axis.
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The node in question.
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the given node falls outside the axis being traversed.
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean isAfterAxis(int axisRoot, int identity)
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %REVIEW% Is there *any* cheaper way to do this?
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Yes. In ID space, compare to axisRoot's successor
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// (next-sib or ancestor's-next-sib). Probably shallower search.
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(identity == axisRoot)
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        identity = m_parent.elementAt(identity);
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while(identity >= axisRoot);
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of origin for the traversal -- its "root node" or starting point.
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isIndexed(expandedTypeID))
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int identity = getSubtreeRoot(context);
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int firstPotential = getFirstPotential(identity);
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(getNextIndexed(identity, firstPotential, expandedTypeID));
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return next(context, context, expandedTypeID);
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = getSubtreeRoot(context);
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) + 1; ; current++)
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type = _type(current);  // may call nextNode()
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isDescendant(subtreeRootIdent, current))
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = getSubtreeRoot(context);
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      current = makeNodeIdentity(current) + 1;
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isIndexed(expandedTypeID))
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(getNextIndexed(subtreeRootIdent, current, expandedTypeID));
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (; ; current++)
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int exptype = _exptype(current);  // may call nextNode()
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isDescendant(subtreeRootIdent, current))
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (exptype != expandedTypeID)
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class DescendantOrSelfTraverser extends DescendantTraverser
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first potential identity that can be returned, which is the
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * axis context, in this case.
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The node identity of the root context of the traversal.
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The axis context.
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getFirstPotential(int identity)
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return identity;
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  To see if
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node should be processed, use this function.
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return context;
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the entire subtree, including the root node.
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class AllFromNodeTraverser extends DescendantOrSelfTraverser
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context);
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) + 1; ; current++)
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Trickological code: _exptype() has the side-effect of
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // running nextNode until the specified node has been loaded,
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // and thus can be used to ensure that incremental construction of
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // the DTM has gotten this far. Using it just for that side-effect
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // is quite a kluge...
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _exptype(current);  // make sure it's here.
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isDescendant(subtreeRootIdent, current))
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the following access, in document order.
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class FollowingTraverser extends DescendantTraverser
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first of the following.
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * that the traversal starts from.
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			context=makeNodeIdentity(context);
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int first;
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int type = _type(context);
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        context = _parent(context);
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        first = _firstch(context);
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL != first)
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return makeNodeHandle(first);
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        first = _nextsib(context);
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL == first)
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          context = _parent(context);
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (NULL == first && NULL != context);
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return makeNodeHandle(first);
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first of the following.
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of origin for the traversal -- its "root node" or starting point.
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// %REVIEW% This looks like it might want shift into identity space
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// to avoid repeated conversion in the individual functions
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int first;
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int type = getNodeType(context);
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        context = getParent(context);
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        first = getFirstChild(context);
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL != first)
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (getExpandedTypeID(first) == expandedTypeID)
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return first;
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return next(context, first, expandedTypeID);
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        first = getNextSibling(context);
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL == first)
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          context = getParent(context);
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (getExpandedTypeID(first) == expandedTypeID)
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return first;
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return next(context, first, expandedTypeID);
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (NULL == first && NULL != context);
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return first;
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in identity space
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			current=makeNodeIdentity(current);
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        current++; // Only works on IDs, not handles.
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson				// %REVIEW% Are we using handles or indexes?
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type = _type(current);  // may call nextNode()
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL == type)
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			current=makeNodeIdentity(current);
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        current++;
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int etype = _exptype(current);  // may call nextNode()
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL == etype)
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (etype != expandedTypeID)
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class FollowingSiblingTraverser extends DTMAxisTraverser
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getNextSibling(current);
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != (current = getNextSibling(current)))
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (getExpandedTypeID(current) == expandedTypeID)
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return current;
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class NamespaceDeclsTraverser extends DTMAxisTraverser
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (context == current)
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             ? getFirstNamespaceNode(context, false)
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             : getNextNamespaceNode(context, current, false);
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      current = (context == current)
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                ? getFirstNamespaceNode(context, false)
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                : getNextNamespaceNode(context, current, false);
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (getExpandedTypeID(current) == expandedTypeID)
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return current;
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             != (current = getNextNamespaceNode(context, current, false)));
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class NamespaceTraverser extends DTMAxisTraverser
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (context == current)
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             ? getFirstNamespaceNode(context, true)
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             : getNextNamespaceNode(context, current, true);
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      current = (context == current)
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                ? getFirstNamespaceNode(context, true)
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                : getNextNamespaceNode(context, current, true);
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (getExpandedTypeID(current) == expandedTypeID)
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return current;
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             != (current = getNextNamespaceNode(context, current, true)));
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class ParentTraverser extends DTMAxisTraverser
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * that the traversal starts from.
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getParent(context);
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of origin for the traversal -- its "root node" or starting point.
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int current, int expandedTypeID)
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      current = makeNodeIdentity(current);
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (NULL != (current = m_parent.elementAt(current)))
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_exptype.elementAt(current) == expandedTypeID)
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return makeNodeHandle(current);
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class PrecedingTraverser extends DTMAxisTraverser
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if the current identity is an ancestor of the context identity.
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This is an expensive operation, made worse by the stateless traversal.
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * But the preceding axis is used fairly infrequently.
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param contextIdent The context node of the axis traversal.
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param currentIdent The node in question.
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the currentIdent node is an ancestor of contextIdent.
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean isAncestor(int contextIdent, int currentIdent)
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// %REVIEW% See comments in IsAfterAxis; using the "successor" of
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// contextIdent is probably more efficient.
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (contextIdent = m_parent.elementAt(contextIdent); DTM.NULL != contextIdent;
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              contextIdent = m_parent.elementAt(contextIdent))
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (contextIdent == currentIdent)
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true;
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// compute in ID space
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context);
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        short type = _type(current);
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                || isAncestor(subtreeRootIdent, current))
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context);
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int exptype = m_exptype.elementAt(current);
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (exptype != expandedTypeID
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                || isAncestor(subtreeRootIdent, current))
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor and the Preceding axis,
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in reverse document order.
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class PrecedingAndAncestorTraverser extends DTMAxisTraverser
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context );
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        short type = _type(current);
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context);
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int exptype = m_exptype.elementAt(current);
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (exptype != expandedTypeID)
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class PrecedingSiblingTraverser extends DTMAxisTraverser
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getPreviousSibling(current);
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != (current = getPreviousSibling(current)))
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (getExpandedTypeID(current) == expandedTypeID)
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return current;
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Self axis.
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class SelfTraverser extends DTMAxisTraverser
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  To see if
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node should be processed, use this function.
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return context;
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  To see if
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node should be processed, use this function.  If the context
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * node does not match the expanded type ID, this function will return
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * false.
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (getExpandedTypeID(context) == expandedTypeID) ? context : NULL;
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return Always return NULL for this axis.
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Ancestor access, in reverse document order.
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class AllFromRootTraverser extends AllFromNodeTraverser
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the root.
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getDocumentRoot(context);
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the root if it matches the expanded type ID.
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (getExpandedTypeID(getDocumentRoot(context)) == expandedTypeID)
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             ? context : next(context, context, expandedTypeID);
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context);
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) + 1; ; current++)
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson				// Kluge test: Just make sure +1 yielded a real node
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type = _type(current);  // may call nextNode()
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (type == NULL)
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// Compute in ID space
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int subtreeRootIdent = makeNodeIdentity(context);
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (current = makeNodeIdentity(current) + 1; ; current++)
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int exptype = _exptype(current);  // may call nextNode()
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (exptype == NULL)
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return NULL;
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (exptype != expandedTypeID)
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(current);  // make handle.
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implements traversal of the Self axis.
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class RootTraverser extends AllFromRootTraverser
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the root if it matches the expanded type ID,
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * else return null (nothing found)
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int root=getDocumentRoot(context);
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (getExpandedTypeID(root) == expandedTypeID)
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	? root : NULL;
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node.
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return Always return NULL for this axis.
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current)
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Traverse to the next node after the current node that is matched
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * by the expanded type ID.
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this iteration.
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param current The current node of the iteration.
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the next node in the iteration, or DTM.NULL.
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next(int context, int current, int expandedTypeID)
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * from and including the root.
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class DescendantOrSelfFromRootTraverser extends DescendantTraverser
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first potential identity that can be returned, which is the axis
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * root context in this case.
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The node identity of the root context of the traversal.
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The identity argument.
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getFirstPotential(int identity)
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return identity;
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first potential identity that can be returned.
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handle handle to the root context.
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return identity of the root of the subtree.
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getSubtreeRoot(int handle)
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// %REVIEW% Shouldn't this always be 0?
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return makeNodeIdentity(getDocument());
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the root.
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getDocumentRoot(context);
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of origin for the traversal -- its "root node" or starting point.
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isIndexed(expandedTypeID))
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int identity = 0;
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int firstPotential = getFirstPotential(identity);
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(getNextIndexed(identity, firstPotential, expandedTypeID));
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int root = first(context);
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return next(root, root, expandedTypeID);
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * from but not including the root.
16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private class DescendantFromRootTraverser extends DescendantTraverser
16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first potential identity that can be returned, which is the axis
16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * root context in this case.
16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The node identity of the root context of the traversal.
16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The identity argument.
16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getFirstPotential(int identity)
16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return _firstch(0);
16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the first potential identity that can be returned.
16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handle handle to the root context.
16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return identity of the root of the subtree.
16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int getSubtreeRoot(int handle)
16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return 0;
17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the root.
17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal.
17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context)
17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return makeNodeHandle(_firstch(0));
17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * By the nature of the stateless traversal, the context node can not be
17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * returned or the iteration will go into an infinate loop.  So to traverse
17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * an axis, the first function must be used to get the first node.
17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>This method needs to be overloaded only by those axis that process
17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the self node. <\p>
17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param context The context node of this traversal. This is the point
17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of origin for the traversal -- its "root node" or starting point.
17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param expandedTypeID The expanded type ID that must match.
17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the first node in the traversal.
17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int first(int context, int expandedTypeID)
17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isIndexed(expandedTypeID))
17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int identity = 0;
17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int firstPotential = getFirstPotential(identity);
17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return makeNodeHandle(getNextIndexed(identity, firstPotential, expandedTypeID));
17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int root = getDocumentRoot(context);
17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return next(root, root, expandedTypeID);
17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1745