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: SAX2DTM2.java 468653 2006-10-28 07:07:05Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.dtm.ref.sax2dtm;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.*;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.ref.*;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.FastStringBuffer;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLString;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLStringDefault;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLStringFactory;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLMessages;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLErrorResources;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.SerializationHandler;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.Source;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Vector;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.SuballocatedIntVector;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.*;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * SAX2DTM2 is an optimized version of SAX2DTM which is used in non-incremental situation.
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * It is used as the super class of the XSLTC SAXImpl. Many of the interfaces in SAX2DTM
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and DTMDefaultBase are overridden in SAX2DTM2 in order to allow fast, efficient
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * access to the DTM model. Some nested iterators in DTMDefaultBaseIterators
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * are also overridden in SAX2DTM2 for performance reasons.
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Performance is the biggest consideration in the design of SAX2DTM2. To make the code most
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * efficient, the incremental support is dropped in SAX2DTM2, which means that you should not
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * use it in incremental situation. To reduce the overhead of pulling data from the DTM model,
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a few core interfaces in SAX2DTM2 have direct access to the internal arrays of the
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * SuballocatedIntVectors.
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The design of SAX2DTM2 may limit its extensibilty. If you have a reason to extend the
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * SAX2DTM model, please extend from SAX2DTM instead of this class.
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * TODO: This class is currently only used by XSLTC. We need to investigate the possibility
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of also using it in Xalan-J Interpretive. Xalan's performance is likely to get an instant
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * boost if we use SAX2DTM2 instead of SAX2DTM in non-incremental case.
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * %MK% The code in this class is critical to the XSLTC_DTM performance. Be very careful
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * when making changes here!
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class SAX2DTM2 extends SAX2DTM
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /****************************************************************
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *       Optimized version of the nested iterators
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   ****************************************************************/
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns all immediate children of a given node
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class ChildrenIterator extends InternalAxisIteratorBase
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Setting start to END should 'close' the iterator,
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * If the iterator is not restartable, this has no effect.
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * %REVIEW% Should it return/throw something in that case,
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * or set current node to END, to indicate request-not-honored?
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = (node == DTM.NULL) ? DTM.NULL
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                          : _firstch2(makeNodeIdentity(node));
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END if no more
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * are available.
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_currentNode != NULL) {
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int node = _currentNode;
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = _nextsib2(node);
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(makeNodeHandle(node));
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return END;
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of ChildrenIterator
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns the parent of a given node. Note that
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * this delivers only a single node; if you want all the ancestors,
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * see AncestorIterator.
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class ParentIterator extends InternalAxisIteratorBase
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private int _nodeType = DTM.NULL;
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (node != DTM.NULL)
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = _parent2(makeNodeIdentity(node));
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = DTM.NULL;
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set the node type of the parent that we're looking for.
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Note that this does _not_ mean "find the nearest ancestor of
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * this type", but "yield the parent if it is of this type".
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type extended type ID.
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return ParentIterator configured with the type filter set.
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setNodeType(final int type)
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = type;
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration. In this case, we return
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * only the immediate parent, _if_ it matches the requested nodeType.
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int result = _currentNode;
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (result == END)
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %OPT% The most common case is handled first.
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_nodeType == NULL) {
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = END;
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(makeNodeHandle(result));
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (_nodeType >= DTM.NTYPES) {
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (_nodeType == _exptype2(result)) {
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = END;
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return returnNode(makeNodeHandle(result));
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (_nodeType == _type2(result)) {
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  _currentNode = END;
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return returnNode(makeNodeHandle(result));
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return DTM.NULL;
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of ParentIterator
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns children of a given type for a given node.
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The functionality chould be achieved by putting a filter on top
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of a basic child iterator, but a specialised iterator is used
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * for efficiency (both speed and size of translet).
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedChildrenIterator extends InternalAxisIteratorBase
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedChildrenIterator
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeType The extended type ID being requested.
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedChildrenIterator(int nodeType)
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = nodeType;
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = (node == DTM.NULL)
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                   ? DTM.NULL
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                   : _firstch2(makeNodeIdentity(_startNode));
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTM.NULL)
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType != DTM.ELEMENT_NODE) {
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != DTM.NULL && _exptype2(node) != nodeType) {
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _nextsib2(node);
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %OPT% If the nodeType is element (matching child::*), we only
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // need to compare the expType with DTM.NTYPES. A child node of
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // an element can be either an element, text, comment or
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // processing instruction node. Only element node has an extended
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // type greater than or equal to DTM.NTYPES.
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	int eType;
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	while (node != DTM.NULL) {
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  eType = _exptype2(node);
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  if (eType >= DTM.NTYPES)
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	    break;
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  else
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	    node = _nextsib2(node);
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	}
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTM.NULL) {
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = DTM.NULL;
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      } else {
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = _nextsib2(node);
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(makeNodeHandle(node));
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the node at the given position.
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int getNodeByPosition(int position)
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (position <= 0)
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int pos = 0;
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType != DTM.ELEMENT_NODE) {
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != DTM.NULL) {
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (_exptype2(node) == nodeType) {
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            pos++;
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (pos == position)
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              return makeNodeHandle(node);
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _nextsib2(node);
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	while (node != DTM.NULL) {
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  if (_exptype2(node) >= DTM.NTYPES) {
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	    pos++;
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	    if (pos == position)
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	      return makeNodeHandle(node);
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  }
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  node = _nextsib2(node);
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	}
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	return NULL;
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedChildrenIterator
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns the namespace nodes as defined by the XPath data model
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * for a given node, filtered by extended type ID.
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class TypedRootIterator extends RootIterator
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedRootIterator
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeType The extended type ID being requested.
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedRootIterator(int nodeType)
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      super();
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = nodeType;
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(_startNode == _currentNode)
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int node = _startNode;
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int expType = _exptype2(makeNodeIdentity(node));
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = node;
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_nodeType >= DTM.NTYPES) {
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (_nodeType == expType) {
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return returnNode(node);
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (expType < DTM.NTYPES) {
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (expType == _nodeType) {
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return returnNode(node);
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else {
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (m_extendedTypes[expType].getNodeType() == _nodeType) {
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return returnNode(node);
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedRootIterator
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns all siblings of a given node.
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class FollowingSiblingIterator extends InternalAxisIteratorBase
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = makeNodeIdentity(node);
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                : _nextsib2(_currentNode);
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return returnNode(makeNodeHandle(_currentNode));
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of FollowingSiblingIterator
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns all following siblings of a given node.
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedFollowingSiblingIterator
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          extends FollowingSiblingIterator
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedFollowingSiblingIterator
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type The extended type ID being requested.
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedFollowingSiblingIterator(int type)
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = type;
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_currentNode == DTM.NULL) {
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType != DTM.ELEMENT_NODE) {
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) != nodeType) {}
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) < DTM.NTYPES) {}
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = node;
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (node == DTM.NULL)
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      ? DTM.NULL
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      : returnNode(makeNodeHandle(node));
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedFollowingSiblingIterator
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns attribute nodes (of what nodes?)
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class AttributeIterator extends InternalAxisIteratorBase
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // assumes caller will pass element nodes
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int node = _currentNode;
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node != NULL) {
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = getNextAttributeIdentity(node);
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(makeNodeHandle(node));
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of AttributeIterator
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns attribute nodes of a given type
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedAttributeIterator extends InternalAxisIteratorBase
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedAttributeIterator
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeType The extended type ID that is requested.
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedAttributeIterator(int nodeType)
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = nodeType;
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // assumes caller will pass element nodes
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = getTypedAttribute(node, _nodeType);
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int node = _currentNode;
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // singleton iterator, since there can only be one attribute of
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // a given type.
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = NULL;
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return returnNode(node);
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedAttributeIterator
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns preceding siblings of a given node
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class PrecedingSiblingIterator extends InternalAxisIteratorBase
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * The node identity of _startNode for this iterator
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int _startNodeID;
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * True if this iterator has a reversed axis.
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true.
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean isReverse()
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = _startNodeID = makeNodeIdentity(node);
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(node == NULL)
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = node;
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return resetPosition();
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type = _type2(node);
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(ExpandedNameTable.ATTRIBUTE == type
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           || ExpandedNameTable.NAMESPACE == type )
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = node;
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Be careful to handle the Document node properly
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = _parent2(node);
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(NULL!=_currentNode)
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = _firstch2(_currentNode);
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = node;
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int node = _currentNode;
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = _nextsib2(node);
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(makeNodeHandle(node));
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of PrecedingSiblingIterator
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns preceding siblings of a given type for
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a given node
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedPrecedingSiblingIterator
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          extends PrecedingSiblingIterator
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedPrecedingSiblingIterator
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type The extended type ID being requested.
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedPrecedingSiblingIterator(int type)
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = type;
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int startNodeID = _startNodeID;
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType != DTM.ELEMENT_NODE) {
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != NULL && node != startNodeID && _exptype2(node) != nodeType) {
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _nextsib2(node);
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != NULL && node != startNodeID && _exptype2(node) < DTM.NTYPES) {
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _nextsib2(node);
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTM.NULL || node == startNodeID) {
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = NULL;
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = _nextsib2(node);
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(makeNodeHandle(node));
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the index of the last node in this iterator.
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int getLast()
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_last != -1)
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return _last;
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      setMark();
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int startNodeID = _startNodeID;
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int last = 0;
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType != DTM.ELEMENT_NODE) {
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != NULL && node != startNodeID) {
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (_exptype2(node) == nodeType) {
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            last++;
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _nextsib2(node);
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != NULL && node != startNodeID) {
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (_exptype2(node) >= DTM.NTYPES) {
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            last++;
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _nextsib2(node);
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      gotoMark();
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (_last = last);
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedPrecedingSiblingIterator
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns preceding nodes of a given node.
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This includes the node set {root+1, start-1}, but excludes
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * all ancestors, attributes, and namespace nodes.
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class PrecedingIterator extends InternalAxisIteratorBase
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The max ancestors, but it can grow... */
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _maxAncestors = 8;
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * The stack of start node + ancestors up to the root of the tree,
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  which we must avoid.
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int[] _stack = new int[_maxAncestors];
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** (not sure yet... -sb) */
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int _sp, _oldsp;
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected int _markedsp, _markedNode, _markedDescendant;
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /* _currentNode precedes candidates.  This is the identity, not the handle! */
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * True if this iterator has a reversed axis.
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true since this iterator is a reversed axis.
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean isReverse()
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Returns a deep copy of this iterator.   The cloned iterator is not reset.
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return a deep copy of this iterator.
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator cloneIterator()
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _isRestartable = false;
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final PrecedingIterator clone = (PrecedingIterator) super.clone();
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int[] stackCopy = new int[_stack.length];
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        System.arraycopy(_stack, 0, stackCopy, 0, _stack.length);
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        clone._stack = stackCopy;
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // return clone.reset();
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return clone;
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      catch (CloneNotSupportedException e)
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = makeNodeIdentity(node);
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // iterator is not a clone
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int parent, index;
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       if (_type2(node) == DTM.ATTRIBUTE_NODE)
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         node = _parent2(node);
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _stack[index = 0] = node;
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       	parent=node;
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	while ((parent = _parent2(parent)) != NULL)
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (++index == _stack.length)
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  {
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    final int[] stack = new int[index*2];
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    System.arraycopy(_stack, 0, stack, 0, index);
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    _stack = stack;
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  }
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  _stack[index] = parent;
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(index>0)
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  --index; // Pop actual root node (if not start) back off the stack
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode=_stack[index]; // Last parent before root node
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _oldsp = _sp = index;
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	// Bugzilla 8324: We were forgetting to skip Attrs and NS nodes.
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	// Also recoded the loop controls for clarity and to flatten out
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	// the tail-recursion.
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	for(++_currentNode; _sp>=0; ++_currentNode)
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	{
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	  if(_currentNode < _stack[_sp])
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	  {
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	    int type = _type2(_currentNode);
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	    if(type != ATTRIBUTE_NODE && type != NAMESPACE_NODE)
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	      return returnNode(makeNodeHandle(_currentNode));
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	  }
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	  else
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	    --_sp;
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	}
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   	return NULL;
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // redefine DTMAxisIteratorBase's reset
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Resets the iterator to the last start node.
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator, which may or may not be the same as this
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *         iterator.
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator reset()
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _sp = _oldsp;
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return resetPosition();
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void setMark() {
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _markedsp = _sp;
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _markedNode = _currentNode;
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _markedDescendant = _stack[0];
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void gotoMark() {
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _sp = _markedsp;
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = _markedNode;
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of PrecedingIterator
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns preceding nodes of agiven type for a
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * given node. This includes the node set {root+1, start-1}, but
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * excludes all ancestors.
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedPrecedingIterator extends PrecedingIterator
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedPrecedingIterator
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type The extended type ID being requested.
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedPrecedingIterator(int type)
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = type;
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType >= DTM.NTYPES) {
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (true) {
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node++;
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (_sp < 0) {
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            node = NULL;
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            break;
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else if (node >= _stack[_sp]) {
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (--_sp < 0) {
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              node = NULL;
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              break;
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else if (_exptype2(node) == nodeType) {
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            break;
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int expType;
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (true) {
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node++;
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (_sp < 0) {
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            node = NULL;
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            break;
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else if (node >= _stack[_sp]) {
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (--_sp < 0) {
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              node = NULL;
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              break;
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else {
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            expType = _exptype2(node);
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (expType < DTM.NTYPES) {
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (expType == nodeType) {
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              }
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else {
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (m_extendedTypes[expType].getNodeType() == nodeType) {
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              }
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = node;
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (node == NULL) ? NULL : returnNode(makeNodeHandle(node));
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedPrecedingIterator
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns following nodes of for a given node.
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class FollowingIterator extends InternalAxisIteratorBase
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //DTMAxisTraverser m_traverser; // easier for now
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public FollowingIterator()
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //m_traverser = getAxisTraverser(Axis.FOLLOWING);
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //_currentNode = m_traverser.first(node);
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = makeNodeIdentity(node);
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int first;
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type = _type2(node);
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = _parent2(node);
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          first = _firstch2(node);
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (NULL != first) {
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = makeNodeHandle(first);
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return resetPosition();
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          first = _nextsib2(node);
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (NULL == first)
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            node = _parent2(node);
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (NULL == first && NULL != node);
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = makeNodeHandle(first);
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // _currentNode precedes possible following(node) nodes
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //_currentNode = m_traverser.next(_startNode, _currentNode);
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int current = makeNodeIdentity(node);
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        current++;
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type = _type2(current);
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (NULL == type) {
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = NULL;
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return returnNode(node);
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = makeNodeHandle(current);
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return returnNode(node);
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of FollowingIterator
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns following nodes of a given type for a given node.
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedFollowingIterator extends FollowingIterator
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedFollowingIterator
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type The extended type ID being requested.
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedFollowingIterator(int type)
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = type;
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int current;
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node;
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int type;
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int currentNodeID = makeNodeIdentity(_currentNode);
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType >= DTM.NTYPES) {
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do {
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = currentNodeID;
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  current = node;
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          do {
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            current++;
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            type = _type2(current);
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          while (type != NULL && (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type));
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          currentNodeID = (type != NULL) ? current : NULL;
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != DTM.NULL && _exptype2(node) != nodeType);
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do {
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = currentNodeID;
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  current = node;
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          do {
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            current++;
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            type = _type2(current);
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          while (type != NULL && (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type));
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          currentNodeID = (type != NULL) ? current : NULL;
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (node != DTM.NULL
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               && (_exptype2(node) != nodeType && _type2(node) != nodeType));
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = makeNodeHandle(currentNodeID);
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (node == DTM.NULL ? DTM.NULL :returnNode(makeNodeHandle(node)));
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedFollowingIterator
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns the ancestors of a given node in document
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * order.  (NOTE!  This was changed from the XSLTC code!)
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class AncestorIterator extends InternalAxisIteratorBase
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // The initial size of the ancestor array
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final int m_blocksize = 32;
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // The array for ancestor nodes. This array will grow dynamically.
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int[] m_ancestors = new int[m_blocksize];
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Number of ancestor nodes in the array
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int m_size = 0;
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int m_ancestorsPos;
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int m_markedPos;
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The real start node for this axes, since _startNode will be adjusted. */
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int m_realStartNode;
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get start to END should 'close' the iterator,
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The root node of the iteration.
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int getStartNode()
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_realStartNode;
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * True if this iterator has a reversed axis.
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true since this iterator is a reversed axis.
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final boolean isReverse()
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Returns a deep copy of this iterator.  The cloned iterator is not reset.
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return a deep copy of this iterator.
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator cloneIterator()
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _isRestartable = false;  // must set to false for any clone
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final AncestorIterator clone = (AncestorIterator) super.clone();
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        clone._startNode = _startNode;
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // return clone.reset();
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return clone;
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      catch (CloneNotSupportedException e)
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_realStartNode = node;
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int nodeID = makeNodeIdentity(node);
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_size = 0;
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (nodeID == DTM.NULL) {
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = DTM.NULL;
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_ancestorsPos = 0;
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return this;
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Start from the current node's parent if
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // _includeSelf is false.
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!_includeSelf) {
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          nodeID = _parent2(nodeID);
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = makeNodeHandle(nodeID);
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (nodeID != END) {
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          //m_ancestors.addElement(node);
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (m_size >= m_ancestors.length)
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int[] newAncestors = new int[m_size * 2];
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length);
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_ancestors = newAncestors;
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_ancestors[m_size++] = node;
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          nodeID = _parent2(nodeID);
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = makeNodeHandle(nodeID);
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_ancestorsPos = m_size - 1;
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = (m_ancestorsPos>=0)
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               ? m_ancestors[m_ancestorsPos]
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               : DTM.NULL;
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Resets the iterator to the last start node.
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator, which may or may not be the same as this
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *         iterator.
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator reset()
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_ancestorsPos = m_size - 1;
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = (m_ancestorsPos >= 0) ? m_ancestors[m_ancestorsPos]
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         : DTM.NULL;
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return resetPosition();
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int next = _currentNode;
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int pos = --m_ancestorsPos;
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = (pos >= 0) ? m_ancestors[m_ancestorsPos]
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                : DTM.NULL;
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return returnNode(next);
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void setMark() {
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_markedPos = m_ancestorsPos;
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void gotoMark() {
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_ancestorsPos = m_markedPos;
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = m_ancestorsPos>=0 ? m_ancestors[m_ancestorsPos]
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         : DTM.NULL;
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of AncestorIterator
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Typed iterator that returns the ancestors of a given node.
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedAncestorIterator extends AncestorIterator
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedAncestorIterator
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type The extended type ID being requested.
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedAncestorIterator(int type)
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = type;
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_realStartNode = node;
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int nodeID = makeNodeIdentity(node);
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_size = 0;
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (nodeID == DTM.NULL) {
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          _currentNode = DTM.NULL;
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_ancestorsPos = 0;
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return this;
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int nodeType = _nodeType;
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!_includeSelf) {
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          nodeID = _parent2(nodeID);
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node = makeNodeHandle(nodeID);
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (nodeType >= DTM.NTYPES) {
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          while (nodeID != END) {
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int eType = _exptype2(nodeID);
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (eType == nodeType) {
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (m_size >= m_ancestors.length)
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              {
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              	int[] newAncestors = new int[m_size * 2];
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              	System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length);
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              	m_ancestors = newAncestors;
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              }
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              m_ancestors[m_size++] = makeNodeHandle(nodeID);
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nodeID = _parent2(nodeID);
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else {
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          while (nodeID != END) {
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int eType = _exptype2(nodeID);
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((eType < DTM.NTYPES && eType == nodeType)
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                || (eType >= DTM.NTYPES
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && m_extendedTypes[eType].getNodeType() == nodeType)) {
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (m_size >= m_ancestors.length)
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              {
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              	int[] newAncestors = new int[m_size * 2];
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              	System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length);
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              	m_ancestors = newAncestors;
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              }
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              m_ancestors[m_size++] = makeNodeHandle(nodeID);
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nodeID = _parent2(nodeID);
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_ancestorsPos = m_size - 1;
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = (m_ancestorsPos>=0)
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               ? m_ancestors[m_ancestorsPos]
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               : DTM.NULL;
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the node at the given position.
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int getNodeByPosition(int position)
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (position > 0 && position <= m_size) {
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_ancestors[position-1];
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Returns the position of the last node within the iteration, as
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * defined by XPath.
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int getLast() {
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_size;
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedAncestorIterator
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns the descendants of a given node.
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class DescendantIterator extends InternalAxisIteratorBase
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Set start to END should 'close' the iterator,
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * i.e. subsequent call to next() should return END.
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Sets the root of the iteration.
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return A DTMAxisIterator set to the start of the iteration.
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public DTMAxisIterator setStartNode(int node)
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (node == DTMDefaultBase.ROOTNODE)
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = getDocument();
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_isRestartable)
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        node = makeNodeIdentity(node);
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _startNode = node;
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (_includeSelf)
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node--;
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        _currentNode = node;
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return resetPosition();
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return this;
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if this node identity is a descendant.  Assumes that
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the node info for the element has already been obtained.
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This one-sided test works only if the parent has been
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * previously tested and is known to be a descendent. It fails if
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the parent is the _startNode's next sibling, or indeed any node
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * that follows _startNode in document order.  That may suffice
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * for this iterator, but it's not really an isDescendent() test.
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * %REVIEW% rename?
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param identity The index number of the node in question.
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if the index is a descendant of _startNode.
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final boolean isDescendant(int identity)
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (_parent2(identity) >= _startNode) || (_startNode == identity);
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int startNode = _startNode;
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (startNode == NULL) {
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_includeSelf && (_currentNode + 1) == startNode)
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return returnNode(makeNodeHandle(++_currentNode)); // | m_dtmIdent);
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int type;
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %OPT% If the startNode is the root node, do not need
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // to do the isDescendant() check.
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (startNode == ROOTNODE) {
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int eType;
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do {
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node++;
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          eType = _exptype2(node);
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (NULL == eType) {
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = NULL;
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return END;
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } while (eType == TEXT_NODE
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 || (type = m_extendedTypes[eType].getNodeType()) == ATTRIBUTE_NODE
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 || type == NAMESPACE_NODE);
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do {
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node++;
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          type = _type2(node);
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (NULL == type ||!isDescendant(node)) {
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = NULL;
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return END;
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } while(ATTRIBUTE_NODE == type || TEXT_NODE == type
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 || NAMESPACE_NODE == type);
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = node;
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return returnNode(makeNodeHandle(node));  // make handle.
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Reset.
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMAxisIterator reset()
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    final boolean temp = _isRestartable;
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    _isRestartable = true;
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setStartNode(makeNodeHandle(_startNode));
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    _isRestartable = temp;
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return this;
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of DescendantIterator
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Typed iterator that returns the descendants of a given node.
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedDescendantIterator extends DescendantIterator
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedDescendantIterator
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeType Extended type ID being requested.
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedDescendantIterator(int nodeType)
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = nodeType;
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int startNode = _startNode;
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_startNode == NULL) {
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int node = _currentNode;
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int expType;
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int nodeType = _nodeType;
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeType != DTM.ELEMENT_NODE)
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node++;
16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  expType = _exptype2(node);
16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (NULL == expType || _parent2(node) < startNode && startNode != node) {
16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = NULL;
16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return END;
16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (expType != nodeType);
16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %OPT% If the start node is root (e.g. in the case of //node),
16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // we can save the isDescendant() check, because all nodes are
16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // descendants of root.
16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (startNode == DTMDefaultBase.ROOTNODE)
16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	do
16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  node++;
16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  expType = _exptype2(node);
16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (NULL == expType) {
16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    _currentNode = NULL;
16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    return END;
16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  }
16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	} while (expType < DTM.NTYPES
16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	        || m_extendedTypes[expType].getNodeType() != DTM.ELEMENT_NODE);
17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do
17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          node++;
17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  expType = _exptype2(node);
17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (NULL == expType || _parent2(node) < startNode && startNode != node) {
17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            _currentNode = NULL;
17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return END;
17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (expType < DTM.NTYPES
17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	       || m_extendedTypes[expType].getNodeType() != DTM.ELEMENT_NODE);
17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = node;
17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return returnNode(makeNodeHandle(node));
17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedDescendantIterator
17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Iterator that returns a given node only if it is of a given type.
17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final class TypedSingletonIterator extends SingletonIterator
17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The extended type ID that was requested. */
17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final int _nodeType;
17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor TypedSingletonIterator
17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeType The extended type ID being requested.
17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public TypedSingletonIterator(int nodeType)
17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _nodeType = nodeType;
17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the next node in the iteration.
17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The next node handle in the iteration, or END.
17469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int next()
17489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final int result = _currentNode;
17519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (result == END)
17529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return DTM.NULL;
17539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      _currentNode = END;
17559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (_nodeType >= DTM.NTYPES) {
17579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (_exptype2(makeNodeIdentity(result)) == _nodeType) {
17589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return returnNode(result);
17599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else {
17629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (_type2(makeNodeIdentity(result)) == _nodeType) {
17639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return returnNode(result);
17649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
17689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end of TypedSingletonIterator
17709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /*******************************************************************
17729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                End of nested iterators
17739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *******************************************************************/
17749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // %OPT% Array references which are used to cache the map0 arrays in
17779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // SuballocatedIntVectors. Using the cached arrays reduces the level
17789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // of indirection and results in better performance than just calling
17799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // SuballocatedIntVector.elementAt().
17809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[] m_exptype_map0;
17819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[] m_nextsib_map0;
17829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[] m_firstch_map0;
17839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[] m_parent_map0;
17849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Double array references to the map arrays in SuballocatedIntVectors.
17869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[][] m_exptype_map;
17879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[][] m_nextsib_map;
17889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[][] m_firstch_map;
17899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int[][] m_parent_map;
17909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // %OPT% Cache the array of extended types in this class
17929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected ExtendedType[] m_extendedTypes;
17939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // A Vector which is used to store the values of attribute, namespace,
17959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // comment and PI nodes.
17969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //
17979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // %OPT% These values are unlikely to be equal. Storing
17989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // them in a plain Vector is more efficient than storing in the
17999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // DTMStringPool because we can save the cost for hash calculation.
18009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //
18019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // %REVISIT% Do we need a custom class (e.g. StringVector) here?
18029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected Vector m_values;
18039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // The current index into the m_values Vector.
18059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int m_valueIndex = 0;
18069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // The maximum value of the current node index.
18089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int m_maxNodeIndex;
18099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Cache the shift and mask values for the SuballocatedIntVectors.
18119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int m_SHIFT;
18129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int m_MASK;
18139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int m_blocksize;
18149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** %OPT% If the offset and length of a Text node are within certain limits,
18169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * we store a bitwise encoded value into an int, using 10 bits (max. 1024)
18179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * for length and 21 bits for offset. We can save two SuballocatedIntVector
18189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * calls for each getStringValueX() and dispatchCharacterEvents() call by
18199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * doing this.
18209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
18219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // The number of bits for the length of a Text node.
18229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final static int TEXT_LENGTH_BITS = 10;
18239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // The number of bits for the offset of a Text node.
18259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final static int TEXT_OFFSET_BITS = 21;
18269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // The maximum length value
18289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final static int TEXT_LENGTH_MAX = (1<<TEXT_LENGTH_BITS) - 1;
18299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // The maximum offset value
18319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final static int TEXT_OFFSET_MAX = (1<<TEXT_OFFSET_BITS) - 1;
18329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // True if we want to build the ID index table.
18349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected boolean m_buildIdIndex = true;
18359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Constant for empty String
18379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static final String EMPTY_STR = "";
18389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Constant for empty XMLString
18409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static final XMLString EMPTY_XML_STR = new XMLStringDefault("");
18419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
18439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a SAX2DTM2 object using the default block size.
18449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
18459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public SAX2DTM2(DTMManager mgr, Source source, int dtmIdentity,
18469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 DTMWSFilter whiteSpaceFilter,
18479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 XMLStringFactory xstringfactory,
18489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 boolean doIndexing)
18499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
18509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this(mgr, source, dtmIdentity, whiteSpaceFilter,
18529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          xstringfactory, doIndexing, DEFAULT_BLOCKSIZE, true, true, false);
18539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
18549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
18569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a SAX2DTM2 object using the given block size.
18579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
18589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public SAX2DTM2(DTMManager mgr, Source source, int dtmIdentity,
18599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 DTMWSFilter whiteSpaceFilter,
18609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 XMLStringFactory xstringfactory,
18619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 boolean doIndexing,
18629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 int blocksize,
18639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 boolean usePrevsib,
18649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 boolean buildIdIndex,
18659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 boolean newNameTable)
18669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
18679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super(mgr, source, dtmIdentity, whiteSpaceFilter,
18699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);
18709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Initialize the values of m_SHIFT and m_MASK.
18729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int shift;
18739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for(shift=0; (blocksize>>>=1) != 0; ++shift);
18749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_blocksize = 1<<shift;
18769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_SHIFT = shift;
18779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_MASK = m_blocksize - 1;
18789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_buildIdIndex = buildIdIndex;
18809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Some documents do not have attribute nodes. That is why
18829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // we set the initial size of this Vector to be small and set
18839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // the increment to a bigger number.
18849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_values = new Vector(32, 512);
18859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_maxNodeIndex = 1 << DTMManager.IDENT_DTM_NODE_BITS;
18879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Set the map0 values in the constructor.
18899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_exptype_map0 = m_exptype.getMap0();
18909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_nextsib_map0 = m_nextsib.getMap0();
18919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_firstch_map0 = m_firstch.getMap0();
18929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_parent_map0  = m_parent.getMap0();
18939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
18949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
18969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Override DTMDefaultBase._exptype() by dropping the incremental code.
18979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
18989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>This one is less efficient than _exptype2. It is only used during
18999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * DTM building. _exptype2 is used after the document is fully built.
19009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _exptype(int identity)
19029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_exptype.elementAt(identity);
19049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
19059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /************************************************************************
19079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             DTM base accessor interfaces
19089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
19099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %OPT% The code in the following interfaces (e.g. _exptype2, etc.) are
19109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * very important to the DTM performance. To have the best performace,
19119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * these several interfaces have direct access to the internal arrays of
19129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the SuballocatedIntVectors. The final modifier also has a noticeable
19139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * impact on performance.
19149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   ***********************************************************************/
19159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase._exptype().
19189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
19199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity A node identity, which <em>must not</em> be equal to
19209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        <code>DTM.NULL</code>
19219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _exptype2(int identity)
19239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //return m_exptype.elementAt(identity);
19259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity < m_blocksize)
19279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_exptype_map0[identity];
19289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_exptype_map[identity>>>m_SHIFT][identity&m_MASK];
19309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
19319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase._nextsib().
19349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
19359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity A node identity, which <em>must not</em> be equal to
19369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        <code>DTM.NULL</code>
19379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _nextsib2(int identity)
19399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //return m_nextsib.elementAt(identity);
19419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity < m_blocksize)
19439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_nextsib_map0[identity];
19449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_nextsib_map[identity>>>m_SHIFT][identity&m_MASK];
19469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
19479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase._firstch().
19509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
19519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity A node identity, which <em>must not</em> be equal to
19529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        <code>DTM.NULL</code>
19539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _firstch2(int identity)
19559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //return m_firstch.elementAt(identity);
19579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity < m_blocksize)
19599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_firstch_map0[identity];
19609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_firstch_map[identity>>>m_SHIFT][identity&m_MASK];
19629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
19639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase._parent().
19669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
19679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity A node identity, which <em>must not</em> be equal to
19689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        <code>DTM.NULL</code>
19699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _parent2(int identity)
19719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //return m_parent.elementAt(identity);
19739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity < m_blocksize)
19759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_parent_map0[identity];
19769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_parent_map[identity>>>m_SHIFT][identity&m_MASK];
19789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
19799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase._type().
19829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
19839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity A node identity, which <em>must not</em> be equal to
19849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        <code>DTM.NULL</code>
19859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _type2(int identity)
19879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //int eType = _exptype2(identity);
19899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int eType;
19909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity < m_blocksize)
19919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      eType = m_exptype_map0[identity];
19929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      eType = m_exptype_map[identity>>>m_SHIFT][identity&m_MASK];
19949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (NULL != eType)
19969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_extendedTypes[eType].getNodeType();
19979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
19999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
20009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
20029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase.getExpandedTypeID(int).
20039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
20049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>This one is only used by DOMAdapter.getExpandedTypeID(int), which
20059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is mostly called from the compiled translets.
20069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
20079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getExpandedTypeID2(int nodeHandle)
20089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
20099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeID = makeNodeIdentity(nodeHandle);
20109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //return (nodeID != NULL) ? _exptype2(nodeID) : NULL;
20129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (nodeID != NULL) {
20149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nodeID < m_blocksize)
20159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_exptype_map0[nodeID];
20169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
20179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_exptype_map[nodeID>>>m_SHIFT][nodeID&m_MASK];
20189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
20209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
20219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
20229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /*************************************************************************
20249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 END of DTM base accessor interfaces
20259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *************************************************************************/
20269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
20299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the node type from the expanded type
20309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
20319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int _exptype2Type(int exptype)
20329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
20339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (NULL != exptype)
20349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_extendedTypes[exptype].getNodeType();
20359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
20369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
20379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
20389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
20409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a prefix either from the uri mapping, or just make
20419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * one up!
20429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
20439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param uri The namespace URI, which may be null.
20449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
20459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The prefix if there is one, or null.
20469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
20479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getIdForNamespace(String uri)
20489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
20499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     int index = m_values.indexOf(uri);
20509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     if (index < 0)
20519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     {
20529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       m_values.addElement(uri);
20539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       return m_valueIndex++;
20549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     }
20559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     else
20569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       return index;
20579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
20589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
20609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Override SAX2DTM.startElement()
20619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
20629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>Receive notification of the start of an element.
20639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
20649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>By default, do nothing.  Application writers may override this
20659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * method in a subclass to take specific actions at the start of
20669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * each element (such as allocating a new tree node or writing
20679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * output to a file).</p>
20689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
20699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param uri The Namespace URI, or the empty string if the
20709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        element has no Namespace URI or if Namespace
20719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        processing is not being performed.
20729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param localName The local name (without prefix), or the
20739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        empty string if Namespace processing is not being
20749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        performed.
20759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param qName The qualified name (with prefix), or the
20769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        empty string if qualified names are not available.
20779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param attributes The specified or defaulted attributes.
20789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException Any SAX exception, possibly
20799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
20809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.xml.sax.ContentHandler#startElement
20819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
20829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void startElement(String uri, String localName, String qName, Attributes attributes)
20839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throws SAXException
20849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
20859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    charactersFlush();
20879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
20899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int prefixIndex = (qName.length() != localName.length())
20919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      ? m_valuesOrPrefixes.stringToIndex(qName) : 0;
20929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int elemNode = addNode(DTM.ELEMENT_NODE, exName,
20949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                           m_parents.peek(), m_previous, prefixIndex, true);
20959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_indexing)
20979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      indexNode(exName, elemNode);
20989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_parents.push(elemNode);
21009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int startDecls = m_contextIndexes.peek();
21029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nDecls = m_prefixMappings.size();
21039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String prefix;
21049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(!m_pastFirstElement)
21069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
21079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // SPECIAL CASE: Implied declaration at root element
21089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prefix="xml";
21099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String declURL = "http://www.w3.org/XML/1998/namespace";
21109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
21119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_values.addElement(declURL);
21129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int val = m_valueIndex++;
21139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      addNode(DTM.NAMESPACE_NODE, exName, elemNode,
21149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                     DTM.NULL, val, false);
21159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_pastFirstElement=true;
21169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = startDecls; i < nDecls; i += 2)
21199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
21209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prefix = (String) m_prefixMappings.elementAt(i);
21219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (prefix == null)
21239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        continue;
21249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String declURL = (String) m_prefixMappings.elementAt(i + 1);
21269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
21289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_values.addElement(declURL);
21309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int val = m_valueIndex++;
21319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      addNode(DTM.NAMESPACE_NODE, exName, elemNode, DTM.NULL, val, false);
21339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int n = attributes.getLength();
21369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = 0; i < n; i++)
21389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
21399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String attrUri = attributes.getURI(i);
21409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String attrQName = attributes.getQName(i);
21419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String valString = attributes.getValue(i);
21429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nodeType;
21449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String attrLocalName = attributes.getLocalName(i);
21469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((null != attrQName)
21489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && (attrQName.equals("xmlns")
21499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  || attrQName.startsWith("xmlns:")))
21509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
21519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        prefix = getPrefix(attrQName, attrUri);
21529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (declAlreadyDeclared(prefix))
21539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;  // go to the next attribute.
21549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nodeType = DTM.NAMESPACE_NODE;
21569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
21579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
21589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
21599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nodeType = DTM.ATTRIBUTE_NODE;
21609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_buildIdIndex && attributes.getType(i).equalsIgnoreCase("ID"))
21629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          setIDAttribute(valString, elemNode);
21639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
21649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Bit of a hack... if somehow valString is null, stringToIndex will
21669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // return -1, which will make things very unhappy.
21679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(null == valString)
21689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        valString = "";
21699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_values.addElement(valString);
21719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int val = m_valueIndex++;
21729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (attrLocalName.length() != attrQName.length())
21749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
21759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);
21779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int dataIndex = m_data.size();
21799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_data.addElement(prefixIndex);
21819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_data.addElement(val);
21829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = -dataIndex;
21849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
21859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType);
21879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      addNode(nodeType, exName, elemNode, DTM.NULL, val,
21889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                     false);
21899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_wsfilter)
21929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
21939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
21949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
21959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            ? getShouldStripWhitespace()
21969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            : (DTMWSFilter.STRIP == wsv);
21979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pushShouldStripWhitespace(shouldStrip);
21999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
22009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_previous = DTM.NULL;
22029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_contextIndexes.push(m_prefixMappings.size());  // for the children.
22049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
22059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
22079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Receive notification of the end of an element.
22089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
22099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>By default, do nothing.  Application writers may override this
22109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * method in a subclass to take specific actions at the end of
22119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * each element (such as finalising a tree node or writing
22129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * output to a file).</p>
22139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
22149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param uri The Namespace URI, or the empty string if the
22159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        element has no Namespace URI or if Namespace
22169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        processing is not being performed.
22179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param localName The local name (without prefix), or the
22189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        empty string if Namespace processing is not being
22199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        performed.
22209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param qName The qualified XML 1.0 name (with prefix), or the
22219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        empty string if qualified names are not available.
22229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException Any SAX exception, possibly
22239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
22249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.xml.sax.ContentHandler#endElement
22259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
22269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void endElement(String uri, String localName, String qName)
22279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws SAXException
22289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
22299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    charactersFlush();
22309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // If no one noticed, startPrefixMapping is a drag.
22329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Pop the context for the last child (the one pushed by startElement)
22339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_contextIndexes.quickPop(1);
22349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Do it again for this one (the one pushed by the last endElement).
22369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int topContextIndex = m_contextIndexes.peek();
22379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (topContextIndex != m_prefixMappings.size()) {
22389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_prefixMappings.setSize(topContextIndex);
22399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
22409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_previous = m_parents.pop();
22429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    popShouldStripWhitespace();
22449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
22459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
22479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Report an XML comment anywhere in the document.
22489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
22499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>This callback will be used for comments inside or outside the
22509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * document element, including comments in the external DTD
22519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * subset (if read).</p>
22529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
22539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param ch An array holding the characters in the comment.
22549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param start The starting position in the array.
22559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param length The number of characters to use from the array.
22569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException The application may raise an exception.
22579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
22589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void comment(char ch[], int start, int length) throws SAXException
22599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
22609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_insideDTD)      // ignore comments if we're inside the DTD
22629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
22639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    charactersFlush();
22659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // %OPT% Saving the comment string in a Vector has a lower cost than
22679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // saving it in DTMStringPool.
22689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_values.addElement(new String(ch, start, length));
22699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int dataIndex = m_valueIndex++;
22709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_previous = addNode(DTM.COMMENT_NODE, DTM.COMMENT_NODE,
22729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         m_parents.peek(), m_previous, dataIndex, false);
22739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
22749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
22769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Receive notification of the beginning of the document.
22779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
22789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException Any SAX exception, possibly
22799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
22809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.xml.sax.ContentHandler#startDocument
22819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
22829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void startDocument() throws SAXException
22839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
22849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int doc = addNode(DTM.DOCUMENT_NODE,
22869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      DTM.DOCUMENT_NODE,
22879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      DTM.NULL, DTM.NULL, 0, true);
22889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_parents.push(doc);
22909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_previous = DTM.NULL;
22919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_contextIndexes.push(m_prefixMappings.size());  // for the next element.
22939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
22949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
22969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Receive notification of the end of the document.
22979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
22989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException Any SAX exception, possibly
22999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
23009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.xml.sax.ContentHandler#endDocument
23019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
23029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void endDocument() throws SAXException
23039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
23049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super.endDocument();
23059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Add a NULL entry to the end of the node arrays as
23079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // the end indication.
23089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_exptype.addElement(NULL);
23099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_parent.addElement(NULL);
23109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_nextsib.addElement(NULL);
23119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_firstch.addElement(NULL);
23129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Set the cached references after the document is built.
23149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_extendedTypes = m_expandedNameTable.getExtendedTypes();
23159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_exptype_map = m_exptype.getMap();
23169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_nextsib_map = m_nextsib.getMap();
23179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_firstch_map = m_firstch.getMap();
23189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_parent_map  = m_parent.getMap();
23199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
23209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
23229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct the node map from the node.
23239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
23249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param type raw type ID, one of DTM.XXX_NODE.
23259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param expandedTypeID The expended type ID.
23269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param parentIndex The current parent index.
23279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param previousSibling The previous sibling index.
23289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param dataOrPrefix index into m_data table, or string handle.
23299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param canHaveFirstChild true if the node can have a first child, false
23309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                          if it is atomic.
23319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
23329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The index identity of the node that was added.
23339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
23349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final int addNode(int type, int expandedTypeID,
23359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int parentIndex, int previousSibling,
23369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int dataOrPrefix, boolean canHaveFirstChild)
23379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
23389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Common to all nodes:
23399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeIndex = m_size++;
23409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Have we overflowed a DTM Identity's addressing range?
23429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
23439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (nodeIndex == m_maxNodeIndex)
23449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
23459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      addNewDTMID(nodeIndex);
23469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_maxNodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS);
23479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
23489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_firstch.addElement(DTM.NULL);
23509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_nextsib.addElement(DTM.NULL);
23519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_parent.addElement(parentIndex);
23529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_exptype.addElement(expandedTypeID);
23539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_dataOrQName.addElement(dataOrPrefix);
23549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_prevsib != null) {
23569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_prevsib.addElement(previousSibling);
23579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
23589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_locator != null && m_useSourceLocationProperty) {
23609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      setSourceLocation();
23619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
23629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Note that nextSibling is not processed until charactersFlush()
23649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // is called, to handle successive characters() events.
23659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Special handling by type: Declare namespaces, attach first child
23679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch(type)
23689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
23699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.NAMESPACE_NODE:
23709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      declareNamespaceInContext(parentIndex,nodeIndex);
23719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
23729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ATTRIBUTE_NODE:
23739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
23749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default:
23759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DTM.NULL != previousSibling) {
23769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_nextsib.setElementAt(nodeIndex,previousSibling);
23779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
23789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (DTM.NULL != parentIndex) {
23799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_firstch.setElementAt(nodeIndex,parentIndex);
23809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
23819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
23829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
23839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return nodeIndex;
23859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
23869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
23889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Check whether accumulated text should be stripped; if not,
23899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * append the appropriate flavor of text/cdata node.
23909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
23919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final void charactersFlush()
23929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
23939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_textPendingStart >= 0)  // -1 indicates no-text-in-progress
23959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
23969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int length = m_chars.size() - m_textPendingStart;
23979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean doStrip = false;
23989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (getShouldStripWhitespace())
24009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
24019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        doStrip = m_chars.isWhitespace(m_textPendingStart, length);
24029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
24039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (doStrip) {
24059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_chars.setLength(m_textPendingStart);  // Discard accumulated text
24069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      } else {
24079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Guard against characters/ignorableWhitespace events that
24089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // contained no characters.  They should not result in a node.
24099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (length > 0) {
24109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // If the offset and length do not exceed the given limits
24119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // (offset < 2^21 and length < 2^10), then save both the offset
24129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // and length in a bitwise encoded value.
24139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (length <= TEXT_LENGTH_MAX
24149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  && m_textPendingStart <= TEXT_OFFSET_MAX) {
24159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
24169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             m_parents.peek(), m_previous,
24179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             length + (m_textPendingStart << TEXT_LENGTH_BITS),
24189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             false);
24199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          } else {
24219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Store offset and length in the m_data array if one exceeds
24229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // the given limits. Use a negative dataIndex as an indication.
24239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int dataIndex = m_data.size();
24249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
24259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               m_parents.peek(), m_previous, -dataIndex, false);
24269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_data.addElement(m_textPendingStart);
24289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_data.addElement(length);
24299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
24309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
24319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
24329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Reset for next text block
24349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_textPendingStart = -1;
24359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_textType = m_coalescedTextType = DTM.TEXT_NODE;
24369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
24379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
24389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
24409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Override the processingInstruction() interface in SAX2DTM2.
24419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
24429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %OPT% This one is different from SAX2DTM.processingInstruction()
24439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in that we do not use extended types for PI nodes. The name of
24449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the PI is saved in the DTMStringPool.
24459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
24469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Receive notification of a processing instruction.
24479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
24489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param target The processing instruction target.
24499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param data The processing instruction data, or null if
24509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             none is supplied.
24519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException Any SAX exception, possibly
24529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
24539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.xml.sax.ContentHandler#processingInstruction
24549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
24559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void processingInstruction(String target, String data)
24569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  throws SAXException
24579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
24589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    charactersFlush();
24609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int dataIndex = m_data.size();
24629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_previous = addNode(DTM.PROCESSING_INSTRUCTION_NODE,
24639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			 DTM.PROCESSING_INSTRUCTION_NODE,
24649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			 m_parents.peek(), m_previous,
24659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			 -dataIndex, false);
24669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_data.addElement(m_valuesOrPrefixes.stringToIndex(target));
24689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_values.addElement(data);
24699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_data.addElement(m_valueIndex++);
24709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
24729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
24749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase.getFirstAttribute().
24759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
24769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node handle, get the index of the node's first attribute.
24779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
24789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle int Handle of the node.
24799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Handle of first attribute, or DTM.NULL to indicate none exists.
24809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
24819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getFirstAttribute(int nodeHandle)
24829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
24839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeID = makeNodeIdentity(nodeHandle);
24849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (nodeID == DTM.NULL)
24869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return DTM.NULL;
24879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type = _type2(nodeID);
24899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DTM.ELEMENT_NODE == type)
24919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
24929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Assume that attributes and namespaces immediately follow the element.
24939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
24949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
24959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        nodeID++;
24969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	// Assume this can not be null.
24979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	type = _type2(nodeID);
24989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
24999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (type == DTM.ATTRIBUTE_NODE)
25009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
25019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return makeNodeHandle(nodeID);
25029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
25039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else if (DTM.NAMESPACE_NODE != type)
25049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
25059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  break;
25069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
25079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
25089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
25099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return DTM.NULL;
25119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
25129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
25149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase.getFirstAttributeIdentity(int).
25159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
25169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node identity, get the index of the node's first attribute.
25179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
25189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity int identity of the node.
25199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Identity of first attribute, or DTM.NULL to indicate none exists.
25209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
25219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int getFirstAttributeIdentity(int identity) {
25229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity == NULL) {
25239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NULL;
25249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
25259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type = _type2(identity);
25269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DTM.ELEMENT_NODE == type)
25289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
25299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Assume that attributes and namespaces immediately follow the element.
25309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
25319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
25329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        identity++;
25339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Assume this can not be null.
25359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        type = _type2(identity);
25369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (type == DTM.ATTRIBUTE_NODE)
25389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
25399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return identity;
25409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
25419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (DTM.NAMESPACE_NODE != type)
25429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
25439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
25449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
25459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
25469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
25479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return DTM.NULL;
25499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
25509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
25529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase.getNextAttributeIdentity(int).
25539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
25549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node identity for an attribute, advance to the next attribute.
25559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
25569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param identity int identity of the attribute node.  This
25579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <strong>must</strong> be an attribute node.
25589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
25599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return int DTM node-identity of the resolved attr,
25609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * or DTM.NULL to indicate none exists.
25619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
25629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
25639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int getNextAttributeIdentity(int identity) {
25649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Assume that attributes and namespace nodes immediately follow the element
25659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (true) {
25669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      identity++;
25679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int type = _type2(identity);
25689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (type == DTM.ATTRIBUTE_NODE) {
25709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return identity;
25719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      } else if (type != DTM.NAMESPACE_NODE) {
25729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
25739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
25749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
25759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return DTM.NULL;
25779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
25789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
25809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of DTMDefaultBase.getTypedAttribute(int, int).
25819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
25829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node handle and an expanded type ID, get the index of the node's
25839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * attribute of that type, if any.
25849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
25859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle int Handle of the node.
25869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param attType int expanded type ID of the required attribute.
25879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Handle of attribute of the required type, or DTM.NULL to indicate
25889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * none exists.
25899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
25909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected final int getTypedAttribute(int nodeHandle, int attType)
25919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
25929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeID = makeNodeIdentity(nodeHandle);
25949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (nodeID == DTM.NULL)
25969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return DTM.NULL;
25979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
25989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type = _type2(nodeID);
25999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DTM.ELEMENT_NODE == type)
26019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
26029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int expType;
26039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
26049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
26059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	nodeID++;
26069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	expType = _exptype2(nodeID);
26079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (expType != DTM.NULL)
26099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  type = m_extendedTypes[expType].getNodeType();
26109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else
26119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return DTM.NULL;
26129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (type == DTM.ATTRIBUTE_NODE)
26149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
26159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (expType == attType) return makeNodeHandle(nodeID);
26169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
26179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else if (DTM.NAMESPACE_NODE != type)
26189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
26199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  break;
26209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
26219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
26229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
26239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return DTM.NULL;
26259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
26269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
26289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Override SAX2DTM.getLocalName() in SAX2DTM2.
26299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>Processing for PIs is different.
26309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
26319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node handle, return its XPath- style localname. (As defined in
26329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Namespaces, this is the portion of the name after any colon character).
26339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
26349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle the id of the node.
26359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String Local name of this node.
26369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
26379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getLocalName(int nodeHandle)
26389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
26399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int expType = _exptype(makeNodeIdentity(nodeHandle));
26409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (expType == DTM.PROCESSING_INSTRUCTION_NODE)
26429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
26439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = _dataOrQName(makeNodeIdentity(nodeHandle));
26449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      dataIndex = m_data.elementAt(-dataIndex);
26459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_valuesOrPrefixes.indexToString(dataIndex);
26469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
26479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
26489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_expandedNameTable.getLocalName(expType);
26499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
26509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
26529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of SAX2DTM.getNodeNameX().
26539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
26549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node handle, return the XPath node name. This should be the name
26559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as described by the XPath data model, NOT the DOM- style name.
26569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
26579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle the id of the node.
26589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String Name of this node, which may be an empty string.
26599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
26609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final String getNodeNameX(int nodeHandle)
26619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
26629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeID = makeNodeIdentity(nodeHandle);
26649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int eType = _exptype2(nodeID);
26659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (eType == DTM.PROCESSING_INSTRUCTION_NODE)
26679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
26689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = _dataOrQName(nodeID);
26699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      dataIndex = m_data.elementAt(-dataIndex);
26709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_valuesOrPrefixes.indexToString(dataIndex);
26719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
26729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    final ExtendedType extType = m_extendedTypes[eType];
26749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (extType.getNamespace().length() == 0)
26769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
26779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return extType.getLocalName();
26789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
26799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
26809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
26819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int qnameIndex = m_dataOrQName.elementAt(nodeID);
26829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (qnameIndex == 0)
26849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return extType.getLocalName();
26859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (qnameIndex < 0)
26879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
26889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	qnameIndex = -qnameIndex;
26899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	qnameIndex = m_data.elementAt(qnameIndex);
26909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
26919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_valuesOrPrefixes.indexToString(qnameIndex);
26939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
26949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
26959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
26969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
26979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of SAX2DTM.getNodeName().
26989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
26999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node handle, return its DOM-style node name. This will include
27009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * names such as #text or #document.
27019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
27029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle the id of the node.
27039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String Name of this node, which may be an empty string.
27049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %REVIEW% Document when empty string is possible...
27059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %REVIEW-COMMENT% It should never be empty, should it?
27069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
27079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getNodeName(int nodeHandle)
27089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
27099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeID = makeNodeIdentity(nodeHandle);
27119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int eType = _exptype2(nodeID);
27129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    final ExtendedType extType = m_extendedTypes[eType];
27149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (extType.getNamespace().length() == 0)
27159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
27169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int type = extType.getNodeType();
27179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String localName = extType.getLocalName();
27199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (type == DTM.NAMESPACE_NODE)
27209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
27219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (localName.length() == 0)
27229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return "xmlns";
27239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else
27249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return "xmlns:" + localName;
27259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
27269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (type == DTM.PROCESSING_INSTRUCTION_NODE)
27279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
27289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int dataIndex = _dataOrQName(nodeID);
27299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	dataIndex = m_data.elementAt(-dataIndex);
27309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	return m_valuesOrPrefixes.indexToString(dataIndex);
27319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
27329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (localName.length() == 0)
27339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
27349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return getFixedNames(type);
27359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
27369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
27379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	return localName;
27389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
27399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
27409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
27419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int qnameIndex = m_dataOrQName.elementAt(nodeID);
27429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (qnameIndex == 0)
27449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return extType.getLocalName();
27459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (qnameIndex < 0)
27479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
27489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	qnameIndex = -qnameIndex;
27499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	qnameIndex = m_data.elementAt(qnameIndex);
27509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
27519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_valuesOrPrefixes.indexToString(qnameIndex);
27539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
27549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
27559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
27579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Override SAX2DTM.getStringValue(int)
27589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
27599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This method is only used by Xalan-J Interpretive. It is not used by XSLTC.
27609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
27619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If the caller supplies an XMLStringFactory, the getStringValue() interface
27629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in SAX2DTM will be called. Otherwise just calls getStringValueX() and
27639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * wraps the returned String in an XMLString.
27649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
27659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the string-value of a node as a String object
27669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * (see http://www.w3.org/TR/xpath#data-model
27679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * for the definition of a node's string-value).
27689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
27699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle The node ID.
27709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
27719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A string object that represents the string-value of the given node.
27729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
27739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XMLString getStringValue(int nodeHandle)
27749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
27759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int identity = makeNodeIdentity(nodeHandle);
27769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity == DTM.NULL)
27779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return EMPTY_XML_STR;
27789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type= _type2(identity);
27809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (type == DTM.ELEMENT_NODE || type == DTM.DOCUMENT_NODE)
27829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
27839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int startNode = identity;
27849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      identity = _firstch2(identity);
27859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DTM.NULL != identity)
27869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
27879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int offset = -1;
27889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int length = 0;
27899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	do
27919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
27929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  type = _exptype2(identity);
27939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
27949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
27959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  {
27969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    int dataIndex = m_dataOrQName.elementAt(identity);
27979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    if (dataIndex >= 0)
27989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
27999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      if (-1 == offset)
28009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      {
28019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                offset = dataIndex >>> TEXT_LENGTH_BITS;
28029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      }
28039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      length += dataIndex & TEXT_LENGTH_MAX;
28059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
28069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    else
28079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
28089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      if (-1 == offset)
28099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      {
28109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                offset = m_data.elementAt(-dataIndex);
28119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      }
28129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      length += m_data.elementAt(-dataIndex + 1);
28149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
28159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  }
28169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  identity++;
28189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	} while (_parent2(identity) >= startNode);
28199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (length > 0)
28219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
28229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (m_xstrf != null)
28239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    return m_xstrf.newstr(m_chars, offset, length);
28249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  else
28259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    return new XMLStringDefault(m_chars.getString(offset, length));
28269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
28279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else
28289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return EMPTY_XML_STR;
28299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
28309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
28319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return EMPTY_XML_STR;
28329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
28339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type)
28349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
28359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
28369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex >= 0)
28379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
28389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	if (m_xstrf != null)
28399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  return m_xstrf.newstr(m_chars, dataIndex >>> TEXT_LENGTH_BITS,
28409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	                 dataIndex & TEXT_LENGTH_MAX);
28419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	else
28429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  return new XMLStringDefault(m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS,
28439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	                              dataIndex & TEXT_LENGTH_MAX));
28449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
28459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
28469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
28479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_xstrf != null)
28489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return m_xstrf.newstr(m_chars, m_data.elementAt(-dataIndex),
28499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                m_data.elementAt(-dataIndex+1));
28509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
28519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return new XMLStringDefault(m_chars.getString(m_data.elementAt(-dataIndex),
28529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                   m_data.elementAt(-dataIndex+1)));
28539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
28549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
28559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
28569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
28579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
28589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex < 0)
28609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
28619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = -dataIndex;
28629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = m_data.elementAt(dataIndex + 1);
28639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
28649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_xstrf != null)
28669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_xstrf.newstr((String)m_values.elementAt(dataIndex));
28679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
28689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return new XMLStringDefault((String)m_values.elementAt(dataIndex));
28699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
28709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
28719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
28739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of SAX2DTM.getStringValue(int).
28749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
28759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %OPT% This is one of the most often used interfaces. Performance is
28769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * critical here. This one is different from SAX2DTM.getStringValue(int) in
28779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that it returns a String instead of a XMLString.
28789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
28799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the string- value of a node as a String object (see http: //www. w3.
28809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * org/TR/xpath#data- model for the definition of a node's string- value).
28819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
28829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle The node ID.
28839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
28849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A string object that represents the string-value of the given node.
28859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
28869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final String getStringValueX(final int nodeHandle)
28879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
28889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int identity = makeNodeIdentity(nodeHandle);
28899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity == DTM.NULL)
28909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return EMPTY_STR;
28919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type= _type2(identity);
28939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
28949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (type == DTM.ELEMENT_NODE || type == DTM.DOCUMENT_NODE)
28959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
28969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int startNode = identity;
28979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      identity = _firstch2(identity);
28989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DTM.NULL != identity)
28999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
29009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int offset = -1;
29019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int length = 0;
29029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	do
29049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
29059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  type = _exptype2(identity);
29069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
29089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  {
29099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    int dataIndex = m_dataOrQName.elementAt(identity);
29109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    if (dataIndex >= 0)
29119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
29129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      if (-1 == offset)
29139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      {
29149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                offset = dataIndex >>> TEXT_LENGTH_BITS;
29159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      }
29169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      length += dataIndex & TEXT_LENGTH_MAX;
29189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
29199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    else
29209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
29219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      if (-1 == offset)
29229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      {
29239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                offset = m_data.elementAt(-dataIndex);
29249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      }
29259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      length += m_data.elementAt(-dataIndex + 1);
29279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
29289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  }
29299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  identity++;
29319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	} while (_parent2(identity) >= startNode);
29329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (length > 0)
29349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
29359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return m_chars.getString(offset, length);
29369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
29379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else
29389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  return EMPTY_STR;
29399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
29409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
29419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return EMPTY_STR;
29429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
29439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type)
29449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
29459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
29469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex >= 0)
29479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
29489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	return m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS,
29499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	                          dataIndex & TEXT_LENGTH_MAX);
29509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
29519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
29529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
29539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_chars.getString(m_data.elementAt(-dataIndex),
29549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  m_data.elementAt(-dataIndex+1));
29559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
29569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
29579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
29589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
29599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
29609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex < 0)
29629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
29639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = -dataIndex;
29649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = m_data.elementAt(dataIndex + 1);
29659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
29669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (String)m_values.elementAt(dataIndex);
29689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
29699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
29709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
29729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Returns the string value of the entire tree
29739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
29749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getStringValue()
29759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
29769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int child = _firstch2(ROOTNODE);
29779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (child == DTM.NULL) return EMPTY_STR;
29789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // optimization: only create StringBuffer if > 1 child
29809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if ((_exptype2(child) == DTM.TEXT_NODE) && (_nextsib2(child) == DTM.NULL))
29819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
29829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(child);
29839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex >= 0)
29849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS, dataIndex & TEXT_LENGTH_MAX);
29859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
29869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_chars.getString(m_data.elementAt(-dataIndex),
29879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  m_data.elementAt(-dataIndex + 1));
29889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
29899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
29909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getStringValueX(getDocument());
29919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
29939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
29949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
29959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optimized version of SAX2DTM.dispatchCharactersEvents(int, ContentHandler, boolean).
29969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
29979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Directly call the
29989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * characters method on the passed ContentHandler for the
29999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
30009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * for the definition of a node's string-value). Multiple calls to the
30019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * ContentHandler's characters methods may well occur for a single call to
30029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * this method.
30039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
30049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle The node ID.
30059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param ch A non-null reference to a ContentHandler.
30069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param normalize true if the content should be normalized according to
30079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the rules for the XPath
30089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <a href="http://www.w3.org/TR/xpath#function-normalize-space">normalize-space</a>
30099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * function.
30109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
30119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws SAXException
30129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
30139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void dispatchCharactersEvents(int nodeHandle, ContentHandler ch,
30149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                             boolean normalize)
30159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws SAXException
30169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
30179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int identity = makeNodeIdentity(nodeHandle);
30199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (identity == DTM.NULL)
30219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
30229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type = _type2(identity);
30249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (type == DTM.ELEMENT_NODE || type == DTM.DOCUMENT_NODE)
30269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
30279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int startNode = identity;
30289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      identity = _firstch2(identity);
30299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DTM.NULL != identity)
30309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
30319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int offset = -1;
30329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	int length = 0;
30339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	do
30359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
30369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  type = _exptype2(identity);
30379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
30399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  {
30409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    int dataIndex = m_dataOrQName.elementAt(identity);
30419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    if (dataIndex >= 0)
30439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
30449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      if (-1 == offset)
30459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      {
30469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                offset = dataIndex >>> TEXT_LENGTH_BITS;
30479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      }
30489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      length += dataIndex & TEXT_LENGTH_MAX;
30509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
30519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    else
30529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    {
30539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      if (-1 == offset)
30549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      {
30559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                offset = m_data.elementAt(-dataIndex);
30569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      }
30579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	      length += m_data.elementAt(-dataIndex + 1);
30599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    }
30609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  }
30619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  identity++;
30639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	} while (_parent2(identity) >= startNode);
30649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if (length > 0)
30669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
30679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(normalize)
30689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_chars.sendNormalizedSAXcharacters(ch, offset, length);
30699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
30709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    m_chars.sendSAXcharacters(ch, offset, length);
30719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
30729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
30739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
30749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type)
30759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
30769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
30779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
30789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex >= 0)
30799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
30809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	if (normalize)
30819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  m_chars.sendNormalizedSAXcharacters(ch, dataIndex >>> TEXT_LENGTH_BITS,
30829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	                                      dataIndex & TEXT_LENGTH_MAX);
30839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	else
30849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	  m_chars.sendSAXcharacters(ch, dataIndex >>> TEXT_LENGTH_BITS,
30859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	                            dataIndex & TEXT_LENGTH_MAX);
30869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
30879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
30889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
30899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (normalize)
30909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_chars.sendNormalizedSAXcharacters(ch, m_data.elementAt(-dataIndex),
30919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                              m_data.elementAt(-dataIndex+1));
30929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
30939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_chars.sendSAXcharacters(ch, m_data.elementAt(-dataIndex),
30949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    m_data.elementAt(-dataIndex+1));
30959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
30969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
30979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
30989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
30999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
31009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex < 0)
31029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
31039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = -dataIndex;
31049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = m_data.elementAt(dataIndex + 1);
31059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
31069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String str = (String)m_values.elementAt(dataIndex);
31089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(normalize)
31109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
31119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                     0, str.length(), ch);
31129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
31139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ch.characters(str.toCharArray(), 0, str.length());
31149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
31159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
31169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
31189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a node handle, return its node value. This is mostly
31199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as defined by the DOM, but may ignore some conveniences.
31209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
31219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
31229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle The node id.
31239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String Value of this node, or null if not
31249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * meaningful for this node type.
31259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
31269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getNodeValue(int nodeHandle)
31279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
31289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int identity = makeNodeIdentity(nodeHandle);
31309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int type = _type2(identity);
31319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (type == DTM.TEXT_NODE || type == DTM.CDATA_SECTION_NODE)
31339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
31349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = _dataOrQName(identity);
31359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex > 0)
31369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
31379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	return m_chars.getString(dataIndex >>> TEXT_LENGTH_BITS,
31389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	                          dataIndex & TEXT_LENGTH_MAX);
31399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
31409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
31419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
31429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_chars.getString(m_data.elementAt(-dataIndex),
31439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  m_data.elementAt(-dataIndex+1));
31449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
31459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
31469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type
31479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             || DTM.DOCUMENT_NODE == type)
31489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
31499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return null;
31509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
31519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
31529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
31539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int dataIndex = m_dataOrQName.elementAt(identity);
31549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (dataIndex < 0)
31569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
31579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = -dataIndex;
31589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dataIndex = m_data.elementAt(dataIndex + 1);
31599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
31609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (String)m_values.elementAt(dataIndex);
31629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
31639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
31649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
31669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Copy the String value of a Text node to a SerializationHandler
31679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
31689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final void copyTextNode(final int nodeID, SerializationHandler handler)
31699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
31709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
31719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (nodeID != DTM.NULL) {
31729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      	    int dataIndex = m_dataOrQName.elementAt(nodeID);
31739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (dataIndex >= 0) {
31749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_chars.sendSAXcharacters(handler,
31759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                          dataIndex >>> TEXT_LENGTH_BITS,
31769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                          dataIndex & TEXT_LENGTH_MAX);
31779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
31789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_chars.sendSAXcharacters(handler, m_data.elementAt(-dataIndex),
31799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                          m_data.elementAt(-dataIndex+1));
31809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
31819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
31829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
31839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
31849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
31859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Copy an Element node to a SerializationHandler.
31869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
31879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeID The node identity
31889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param exptype The expanded type of the Element node
31899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handler The SerializationHandler
31909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The qualified name of the Element node.
31919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
31929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final String copyElement(int nodeID, int exptype,
31939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               SerializationHandler handler)
31949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
31959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
31969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final ExtendedType extType = m_extendedTypes[exptype];
31979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String uri = extType.getNamespace();
31989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String name = extType.getLocalName();
31999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (uri.length() == 0) {
32019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            handler.startElement(name);
32029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return name;
32039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
32049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else {
32059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int qnameIndex = m_dataOrQName.elementAt(nodeID);
32069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (qnameIndex == 0) {
32089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                handler.startElement(name);
32099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                handler.namespaceAfterStartElement(EMPTY_STR, uri);
32109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return name;
32119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
32129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (qnameIndex < 0) {
32149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	        qnameIndex = -qnameIndex;
32159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	        qnameIndex = m_data.elementAt(qnameIndex);
32169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
32179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String qName = m_valuesOrPrefixes.indexToString(qnameIndex);
32199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            handler.startElement(qName);
32209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int prefixIndex = qName.indexOf(':');
32219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String prefix;
32229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (prefixIndex > 0) {
32239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                prefix = qName.substring(0, prefixIndex);
32249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
32259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else {
32269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                prefix = null;
32279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
32289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            handler.namespaceAfterStartElement(prefix, uri);
32299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return qName;
32309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
32319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
32339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
32359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Copy  namespace nodes.
32369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
32379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeID The Element node identity
32389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handler The SerializationHandler
32399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param inScope  true if all namespaces in scope should be copied,
32409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  false if only the namespace declarations should be copied.
32419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
32429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final void copyNS(final int nodeID, SerializationHandler handler, boolean inScope)
32439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
32449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
32459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // %OPT% Optimization for documents which does not have any explicit
32469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // namespace nodes. For these documents, there is an implicit
32479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // namespace node (xmlns:xml="http://www.w3.org/XML/1998/namespace")
32489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // declared on the root element node. In this case, there is no
32499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // need to do namespace copying. We can safely return without
32509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // doing anything.
32519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_namespaceDeclSetElements != null &&
32529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_namespaceDeclSetElements.size() == 1 &&
32539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_namespaceDeclSets != null &&
32549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            ((SuballocatedIntVector)m_namespaceDeclSets.elementAt(0))
32559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            .size() == 1)
32569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
32579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        SuballocatedIntVector nsContext = null;
32599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int nextNSNode;
32609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Find the first namespace node
32629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (inScope) {
32639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nsContext = findNamespaceContext(nodeID);
32649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (nsContext == null || nsContext.size() < 1)
32659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
32669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
32679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                nextNSNode = makeNodeIdentity(nsContext.elementAt(0));
32689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
32699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
32709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nextNSNode = getNextNamespaceNode2(nodeID);
32719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int nsIndex = 1;
32739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (nextNSNode != DTM.NULL) {
32749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Retrieve the name of the namespace node
32759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int eType = _exptype2(nextNSNode);
32769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String nodeName = m_extendedTypes[eType].getLocalName();
32779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Retrieve the node value of the namespace node
32799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int dataIndex = m_dataOrQName.elementAt(nextNSNode);
32809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (dataIndex < 0) {
32829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                dataIndex = -dataIndex;
32839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                dataIndex = m_data.elementAt(dataIndex + 1);
32849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
32859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String nodeValue = (String)m_values.elementAt(dataIndex);
32879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            handler.namespaceAfterStartElement(nodeName, nodeValue);
32899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
32909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (inScope) {
32919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (nsIndex < nsContext.size()) {
32929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    nextNSNode = makeNodeIdentity(nsContext.elementAt(nsIndex));
32939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    nsIndex++;
32949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
32959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
32969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return;
32979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
32989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
32999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                nextNSNode = getNextNamespaceNode2(nextNSNode);
33009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
33019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
33029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
33049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the next namespace node following the given base node.
33059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
33069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @baseID The node identity of the base node, which can be an
33079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * element, attribute or namespace node.
33089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The namespace node immediately following the base node.
33099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
33109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final int getNextNamespaceNode2(int baseID) {
33119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int type;
33129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while ((type = _type2(++baseID)) == DTM.ATTRIBUTE_NODE);
33139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (type == DTM.NAMESPACE_NODE)
33159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return baseID;
33169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
33179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return NULL;
33189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
33199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
33219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Copy  attribute nodes from an element .
33229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
33239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeID The Element node identity
33249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handler The SerializationHandler
33259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
33269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final void copyAttributes(final int nodeID, SerializationHandler handler)
33279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException{
33289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       for(int current = getFirstAttributeIdentity(nodeID); current != DTM.NULL; current = getNextAttributeIdentity(current)){
33309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int eType = _exptype2(current);
33319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            copyAttribute(current, eType, handler);
33329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       }
33339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
33349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
33389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Copy an Attribute node to a SerializationHandler
33399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
33409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nodeID The node identity
33419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param exptype The expanded type of the Element node
33429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handler The SerializationHandler
33439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
33449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected final void copyAttribute(int nodeID, int exptype,
33459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        SerializationHandler handler)
33469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
33479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
33489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /*
33499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final String uri = getNamespaceName(node);
33509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (uri.length() != 0) {
33519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                final String prefix = getPrefix(node);
33529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                handler.namespaceAfterStartElement(prefix, uri);
33539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
33549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            handler.addAttribute(getNodeName(node), getNodeValue(node));
33559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        */
33569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final ExtendedType extType = m_extendedTypes[exptype];
33579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String uri = extType.getNamespace();
33589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String localName = extType.getLocalName();
33599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String prefix = null;
33619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String qname = null;
33629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int dataIndex = _dataOrQName(nodeID);
33639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int valueIndex = dataIndex;
33649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (dataIndex <= 0) {
33659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                int prefixIndex = m_data.elementAt(-dataIndex);
33669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                valueIndex = m_data.elementAt(-dataIndex+1);
33679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                qname = m_valuesOrPrefixes.indexToString(prefixIndex);
33689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                int colonIndex = qname.indexOf(':');
33699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (colonIndex > 0) {
33709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    prefix = qname.substring(0, colonIndex);
33719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
33729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
33739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (uri.length() != 0) {
33749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                handler.namespaceAfterStartElement(prefix, uri);
33759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
33769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String nodeName = (prefix != null) ? qname : localName;
33789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String nodeValue = (String)m_values.elementAt(valueIndex);
33799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        handler.addAttribute(nodeName, nodeValue);
33819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
33829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
33839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3384