- /*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * $Id: DTMDefaultBaseIterators.java,v 1.21 2004/02/16 23:06:11 minchau Exp $
- */
- package com.sun.org.apache.xml.internal.dtm.ref;
-
- import com.sun.org.apache.xml.internal.dtm.*;
-
- import javax.xml.transform.Source;
-
- import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
-
- import com.sun.org.apache.xml.internal.res.XMLErrorResources;
- import com.sun.org.apache.xml.internal.res.XMLMessages;
-
-
- /**
- * This class implements the traversers for DTMDefaultBase.
- */
- public abstract class DTMDefaultBaseIterators extends DTMDefaultBaseTraversers
- {
-
- /**
- * Construct a DTMDefaultBaseTraversers object from a DOM node.
- *
- * @param mgr The DTMManager who owns this DTM.
- * @param domSource the DOM source that this DTM will wrap.
- * @param source The object that is used to specify the construction source.
- * @param dtmIdentity The DTM identity ID for this DTM.
- * @param whiteSpaceFilter The white space filter for this DTM, which may
- * be null.
- * @param xstringfactory The factory to use for creating XMLStrings.
- * @param doIndexing true if the caller considers it worth it to use
- * indexing schemes.
- */
- public DTMDefaultBaseIterators(DTMManager mgr, Source source,
- int dtmIdentity,
- DTMWSFilter whiteSpaceFilter,
- XMLStringFactory xstringfactory,
- boolean doIndexing)
- {
- super(mgr, source, dtmIdentity, whiteSpaceFilter,
- xstringfactory, doIndexing);
- }
-
- /**
- * Construct a DTMDefaultBaseTraversers object from a DOM node.
- *
- * @param mgr The DTMManager who owns this DTM.
- * @param domSource the DOM source that this DTM will wrap.
- * @param source The object that is used to specify the construction source.
- * @param dtmIdentity The DTM identity ID for this DTM.
- * @param whiteSpaceFilter The white space filter for this DTM, which may
- * be null.
- * @param xstringfactory The factory to use for creating XMLStrings.
- * @param doIndexing true if the caller considers it worth it to use
- * indexing schemes.
- * @param blocksize The block size of the DTM.
- * @param usePrevsib true if we want to build the previous sibling node array.
- * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
- */
- public DTMDefaultBaseIterators(DTMManager mgr, Source source,
- int dtmIdentity,
- DTMWSFilter whiteSpaceFilter,
- XMLStringFactory xstringfactory,
- boolean doIndexing,
- int blocksize,
- boolean usePrevsib,
- boolean newNameTable)
- {
- super(mgr, source, dtmIdentity, whiteSpaceFilter,
- xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);
- }
-
- /**
- * Get an iterator that can navigate over an XPath Axis, predicated by
- * the extended type ID.
- * Returns an iterator that must be initialized
- * with a start node (using iterator.setStartNode()).
- *
- * @param axis One of Axes.ANCESTORORSELF, etc.
- * @param type An extended type ID.
- *
- * @return A DTMAxisIterator, or null if the given axis isn't supported.
- */
- public DTMAxisIterator getTypedAxisIterator(int axis, int type)
- {
-
- DTMAxisIterator iterator = null;
-
- /* This causes an error when using patterns for elements that
- do not exist in the DOM (translet types which do not correspond
- to a DOM type are mapped to the DOM.ELEMENT type).
- */
-
- // if (type == NO_TYPE) {
- // return(EMPTYITERATOR);
- // }
- // else if (type == ELEMENT) {
- // iterator = new FilterIterator(getAxisIterator(axis),
- // getElementFilter());
- // }
- // else
- {
- switch (axis)
- {
- case Axis.SELF :
- iterator = new TypedSingletonIterator(type);
- break;
- case Axis.CHILD :
- iterator = new TypedChildrenIterator(type);
- break;
- case Axis.PARENT :
- return (new ParentIterator().setNodeType(type));
- case Axis.ANCESTOR :
- return (new TypedAncestorIterator(type));
- case Axis.ANCESTORORSELF :
- return ((new TypedAncestorIterator(type)).includeSelf());
- case Axis.ATTRIBUTE :
- return (new TypedAttributeIterator(type));
- case Axis.DESCENDANT :
- iterator = new TypedDescendantIterator(type);
- break;
- case Axis.DESCENDANTORSELF :
- iterator = (new TypedDescendantIterator(type)).includeSelf();
- break;
- case Axis.FOLLOWING :
- iterator = new TypedFollowingIterator(type);
- break;
- case Axis.PRECEDING :
- iterator = new TypedPrecedingIterator(type);
- break;
- case Axis.FOLLOWINGSIBLING :
- iterator = new TypedFollowingSiblingIterator(type);
- break;
- case Axis.PRECEDINGSIBLING :
- iterator = new TypedPrecedingSiblingIterator(type);
- break;
- case Axis.NAMESPACE :
- iterator = new TypedNamespaceIterator(type);
- break;
- case Axis.ROOT :
- iterator = new TypedRootIterator(type);
- break;
- default :
- throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED, new Object[]{Axis.names[axis]})); //"Error: typed iterator for axis "
- //+ Axis.names[axis] + "not implemented");
- }
- }
-
- return (iterator);
- }
-
- /**
- * This is a shortcut to the iterators that implement the
- * XPath axes.
- * Returns a bare-bones iterator that must be initialized
- * with a start node (using iterator.setStartNode()).
- *
- * @param axis One of Axes.ANCESTORORSELF, etc.
- *
- * @return A DTMAxisIterator, or null if the given axis isn't supported.
- */
- public DTMAxisIterator getAxisIterator(final int axis)
- {
-
- DTMAxisIterator iterator = null;
-
- switch (axis)
- {
- case Axis.SELF :
- iterator = new SingletonIterator();
- break;
- case Axis.CHILD :
- iterator = new ChildrenIterator();
- break;
- case Axis.PARENT :
- return (new ParentIterator());
- case Axis.ANCESTOR :
- return (new AncestorIterator());
- case Axis.ANCESTORORSELF :
- return ((new AncestorIterator()).includeSelf());
- case Axis.ATTRIBUTE :
- return (new AttributeIterator());
- case Axis.DESCENDANT :
- iterator = new DescendantIterator();
- break;
- case Axis.DESCENDANTORSELF :
- iterator = (new DescendantIterator()).includeSelf();
- break;
- case Axis.FOLLOWING :
- iterator = new FollowingIterator();
- break;
- case Axis.PRECEDING :
- iterator = new PrecedingIterator();
- break;
- case Axis.FOLLOWINGSIBLING :
- iterator = new FollowingSiblingIterator();
- break;
- case Axis.PRECEDINGSIBLING :
- iterator = new PrecedingSiblingIterator();
- break;
- case Axis.NAMESPACE :
- iterator = new NamespaceIterator();
- break;
- case Axis.ROOT :
- iterator = new RootIterator();
- break;
- default :
- throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_AXIS_NOT_IMPLEMENTED, new Object[]{Axis.names[axis]})); //"Error: iterator for axis '" + Axis.names[axis]
- //+ "' not implemented");
- }
-
- return (iterator);
- }
-
- /**
- * Abstract superclass defining behaviors shared by all DTMDefault's
- * internal implementations of DTMAxisIterator. Subclass this (and
- * override, if necessary) to implement the specifics of an
- * individual axis iterator.
- *
- * Currently there isn't a lot here
- */
- public abstract class InternalAxisIteratorBase extends DTMAxisIteratorBase
- {
-
- // %REVIEW% We could opt to share _nodeType and setNodeType() as
- // well, and simply ignore them in iterators which don't use them.
- // But Scott's worried about the overhead involved in cloning
- // these, and wants them to have as few fields as possible. Note
- // that we can't create a TypedInternalAxisIteratorBase because
- // those are often based on the untyped versions and Java doesn't
- // support multiple inheritance. <sigh/>
-
- /**
- * Current iteration location. Usually this is the last location
- * returned (starting point for the next() search); for single-node
- * iterators it may instead be initialized to point to that single node.
- */
- protected int _currentNode;
-
- /**
- * Remembers the current node for the next call to gotoMark().
- *
- * %REVIEW% Should this save _position too?
- */
- public void setMark()
- {
- _markedNode = _currentNode;
- }
-
- /**
- * Restores the current node remembered by setMark().
- *
- * %REVEIW% Should this restore _position too?
- */
- public void gotoMark()
- {
- _currentNode = _markedNode;
- }
-
- } // end of InternalAxisIteratorBase
-
- /**
- * Iterator that returns all immediate children of a given node
- */
- public final class ChildrenIterator extends InternalAxisIteratorBase
- {
-
- /**
- * Setting start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * If the iterator is not restartable, this has no effect.
- * %REVIEW% Should it return/throw something in that case,
- * or set current node to END, to indicate request-not-honored?
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = (node == DTM.NULL) ? DTM.NULL
- : _firstch(makeNodeIdentity(node));
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END if no more
- * are available.
- */
- public int next()
- {
- if (_currentNode != NULL) {
- int node = _currentNode;
- _currentNode = _nextsib(node);
- return returnNode(makeNodeHandle(node));
- }
-
- return END;
- }
- } // end of ChildrenIterator
-
- /**
- * Iterator that returns the parent of a given node. Note that
- * this delivers only a single node; if you want all the ancestors,
- * see AncestorIterator.
- */
- public final class ParentIterator extends InternalAxisIteratorBase
- {
-
- /** The extended type ID that was requested. */
- private int _nodeType = -1;
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = getParent(node);
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Set the node type of the parent that we're looking for.
- * Note that this does _not_ mean "find the nearest ancestor of
- * this type", but "yield the parent if it is of this type".
- *
- *
- * @param type extended type ID.
- *
- * @return ParentIterator configured with the type filter set.
- */
- public DTMAxisIterator setNodeType(final int type)
- {
-
- _nodeType = type;
-
- return this;
- }
-
- /**
- * Get the next node in the iteration. In this case, we return
- * only the immediate parent, _if_ it matches the requested nodeType.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- int result = _currentNode;
-
- if (_nodeType >= DTM.NTYPES) {
- if (_nodeType != getExpandedTypeID(_currentNode)) {
- result = END;
- }
- } else if (_nodeType != NULL) {
- if (_nodeType != getNodeType(_currentNode)) {
- result = END;
- }
- }
-
- _currentNode = END;
-
- return returnNode(result);
- }
- } // end of ParentIterator
-
- /**
- * Iterator that returns children of a given type for a given node.
- * The functionality chould be achieved by putting a filter on top
- * of a basic child iterator, but a specialised iterator is used
- * for efficiency (both speed and size of translet).
- */
- public final class TypedChildrenIterator extends InternalAxisIteratorBase
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedChildrenIterator
- *
- *
- * @param nodeType The extended type ID being requested.
- */
- public TypedChildrenIterator(int nodeType)
- {
- _nodeType = nodeType;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = (node == DTM.NULL)
- ? DTM.NULL
- : _firstch(makeNodeIdentity(_startNode));
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- int eType;
- int node = _currentNode;
-
- int nodeType = _nodeType;
-
- if (nodeType >= DTM.NTYPES) {
- while (node != DTM.NULL && _exptype(node) != nodeType) {
- node = _nextsib(node);
- }
- } else {
- while (node != DTM.NULL) {
- eType = _exptype(node);
- if (eType < DTM.NTYPES) {
- if (eType == nodeType) {
- break;
- }
- } else if (m_expandedNameTable.getType(eType) == nodeType) {
- break;
- }
- node = _nextsib(node);
- }
- }
-
- if (node == DTM.NULL) {
- _currentNode = DTM.NULL;
- return DTM.NULL;
- } else {
- _currentNode = _nextsib(node);
- return returnNode(makeNodeHandle(node));
- }
-
- }
- } // end of TypedChildrenIterator
-
- /**
- * Iterator that returns children within a given namespace for a
- * given node. The functionality chould be achieved by putting a
- * filter on top of a basic child iterator, but a specialised
- * iterator is used for efficiency (both speed and size of translet).
- */
- public final class NamespaceChildrenIterator
- extends InternalAxisIteratorBase
- {
-
- /** The extended type ID being requested. */
- private final int _nsType;
-
- /**
- * Constructor NamespaceChildrenIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public NamespaceChildrenIterator(final int type)
- {
- _nsType = type;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED;
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- if (_currentNode != DTM.NULL) {
- for (int node = (NOTPROCESSED == _currentNode)
- ? _firstch(makeNodeIdentity(_startNode))
- : _nextsib(_currentNode);
- node != END;
- node = _nextsib(node)) {
- if (m_expandedNameTable.getNamespaceID(_exptype(node)) == _nsType) {
- _currentNode = node;
-
- return returnNode(node);
- }
- }
- }
-
- return END;
- }
- } // end of NamespaceChildrenIterator
-
- /**
- * Iterator that returns the namespace nodes as defined by the XPath data model
- * for a given node.
- */
- public class NamespaceIterator
- extends InternalAxisIteratorBase
- {
-
- /**
- * Constructor NamespaceAttributeIterator
- */
- public NamespaceIterator()
- {
-
- super();
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = getFirstNamespaceNode(node, true);
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- int node = _currentNode;
-
- if (DTM.NULL != node)
- _currentNode = getNextNamespaceNode(_startNode, node, true);
-
- return returnNode(node);
- }
- } // end of NamespaceIterator
-
- /**
- * Iterator that returns the namespace nodes as defined by the XPath data model
- * for a given node, filtered by extended type ID.
- */
- public class TypedNamespaceIterator extends NamespaceIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedNamespaceIterator
- *
- *
- * @param nodeType The extended type ID being requested.
- */
- public TypedNamespaceIterator(int nodeType)
- {
- super();
- _nodeType = nodeType;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- int node;
-
- for (node = _currentNode;
- node != END;
- node = getNextNamespaceNode(_startNode, node, true)) {
- if (getExpandedTypeID(node) == _nodeType
- || getNodeType(node) == _nodeType
- || getNamespaceType(node) == _nodeType) {
- _currentNode = node;
-
- return returnNode(node);
- }
- }
-
- return (_currentNode =END);
- }
- } // end of TypedNamespaceIterator
-
- /**
- * Iterator that returns the the root node as defined by the XPath data model
- * for a given node.
- */
- public class RootIterator
- extends InternalAxisIteratorBase
- {
-
- /**
- * Constructor RootIterator
- */
- public RootIterator()
- {
-
- super();
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
-
- if (_isRestartable)
- {
- _startNode = getDocumentRoot(node);
- _currentNode = NULL;
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- if(_startNode == _currentNode)
- return NULL;
-
- _currentNode = _startNode;
-
- return returnNode(_startNode);
- }
- } // end of RootIterator
-
- /**
- * Iterator that returns the namespace nodes as defined by the XPath data model
- * for a given node, filtered by extended type ID.
- */
- public class TypedRootIterator extends RootIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedRootIterator
- *
- * @param nodeType The extended type ID being requested.
- */
- public TypedRootIterator(int nodeType)
- {
- super();
- _nodeType = nodeType;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- if(_startNode == _currentNode)
- return NULL;
-
- int nodeType = _nodeType;
- int node = _startNode;
- int expType = getExpandedTypeID(node);
-
- _currentNode = node;
-
- if (nodeType >= DTM.NTYPES) {
- if (nodeType == expType) {
- return returnNode(node);
- }
- } else {
- if (expType < DTM.NTYPES) {
- if (expType == nodeType) {
- return returnNode(node);
- }
- } else {
- if (m_expandedNameTable.getType(expType) == nodeType) {
- return returnNode(node);
- }
- }
- }
-
- return END;
- }
- } // end of TypedRootIterator
-
- /**
- * Iterator that returns attributes within a given namespace for a node.
- */
- public final class NamespaceAttributeIterator
- extends InternalAxisIteratorBase
- {
-
- /** The extended type ID being requested. */
- private final int _nsType;
-
- /**
- * Constructor NamespaceAttributeIterator
- *
- *
- * @param nsType The extended type ID being requested.
- */
- public NamespaceAttributeIterator(int nsType)
- {
-
- super();
-
- _nsType = nsType;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = getFirstNamespaceNode(node, false);
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- int node = _currentNode;
-
- if (DTM.NULL != node)
- _currentNode = getNextNamespaceNode(_startNode, node, false);
-
- return returnNode(node);
- }
- } // end of NamespaceAttributeIterator
-
- /**
- * Iterator that returns all siblings of a given node.
- */
- public class FollowingSiblingIterator extends InternalAxisIteratorBase
- {
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = makeNodeIdentity(node);
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- _currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
- : _nextsib(_currentNode);
- return returnNode(makeNodeHandle(_currentNode));
- }
- } // end of FollowingSiblingIterator
-
- /**
- * Iterator that returns all following siblings of a given node.
- */
- public final class TypedFollowingSiblingIterator
- extends FollowingSiblingIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedFollowingSiblingIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public TypedFollowingSiblingIterator(int type)
- {
- _nodeType = type;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- if (_currentNode == DTM.NULL) {
- return DTM.NULL;
- }
-
- int node = _currentNode;
- int eType;
- int nodeType = _nodeType;
-
- if (nodeType >= DTM.NTYPES) {
- do {
- node = _nextsib(node);
- } while (node != DTM.NULL && _exptype(node) != nodeType);
- } else {
- while ((node = _nextsib(node)) != DTM.NULL) {
- eType = _exptype(node);
- if (eType < DTM.NTYPES) {
- if (eType == nodeType) {
- break;
- }
- } else if (m_expandedNameTable.getType(eType) == nodeType) {
- break;
- }
- }
- }
-
- _currentNode = node;
-
- return (_currentNode == DTM.NULL)
- ? DTM.NULL
- : returnNode(makeNodeHandle(_currentNode));
- }
- } // end of TypedFollowingSiblingIterator
-
- /**
- * Iterator that returns attribute nodes (of what nodes?)
- */
- public final class AttributeIterator extends InternalAxisIteratorBase
- {
-
- // assumes caller will pass element nodes
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- final int node = _currentNode;
-
- if (node != NULL) {
- _currentNode = getNextAttributeIdentity(node);
- return returnNode(makeNodeHandle(node));
- }
-
- return NULL;
- }
- } // end of AttributeIterator
-
- /**
- * Iterator that returns attribute nodes of a given type
- */
- public final class TypedAttributeIterator extends InternalAxisIteratorBase
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedAttributeIterator
- *
- *
- * @param nodeType The extended type ID that is requested.
- */
- public TypedAttributeIterator(int nodeType)
- {
- _nodeType = nodeType;
- }
-
- // assumes caller will pass element nodes
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- if (_isRestartable)
- {
- _startNode = node;
-
- _currentNode = getTypedAttribute(node, _nodeType);
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- final int node = _currentNode;
-
- // singleton iterator, since there can only be one attribute of
- // a given type.
- _currentNode = NULL;
-
- return returnNode(node);
- }
- } // end of TypedAttributeIterator
-
- /**
- * Iterator that returns preceding siblings of a given node
- */
- public class PrecedingSiblingIterator extends InternalAxisIteratorBase
- {
-
- /**
- * The node identity of _startNode for this iterator
- */
- protected int _startNodeID;
-
- /**
- * True if this iterator has a reversed axis.
- *
- * @return true.
- */
- public boolean isReverse()
- {
- return true;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
- node = _startNodeID = makeNodeIdentity(node);
-
- if(node == NULL)
- {
- _currentNode = node;
- return resetPosition();
- }
-
- int type = m_expandedNameTable.getType(_exptype(node));
- if(ExpandedNameTable.ATTRIBUTE == type
- || ExpandedNameTable.NAMESPACE == type )
- {
- _currentNode = node;
- }
- else
- {
- // Be careful to handle the Document node properly
- _currentNode = _parent(node);
- if(NULL!=_currentNode)
- _currentNode = _firstch(_currentNode);
- else
- _currentNode = node;
- }
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
- {
- return NULL;
- }
- else
- {
- final int node = _currentNode;
- _currentNode = _nextsib(node);
-
- return returnNode(makeNodeHandle(node));
- }
- }
- } // end of PrecedingSiblingIterator
-
- /**
- * Iterator that returns preceding siblings of a given type for
- * a given node
- */
- public final class TypedPrecedingSiblingIterator
- extends PrecedingSiblingIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedPrecedingSiblingIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public TypedPrecedingSiblingIterator(int type)
- {
- _nodeType = type;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- int node = _currentNode;
- int expType;
-
- int nodeType = _nodeType;
- int startID = _startNodeID;
-
- if (nodeType >= DTM.NTYPES) {
- while (node != NULL && node != startID && _exptype(node) != nodeType) {
- node = _nextsib(node);
- }
- } else {
- while (node != NULL && node != startID) {
- expType = _exptype(node);
- if (expType < DTM.NTYPES) {
- if (expType == nodeType) {
- break;
- }
- } else {
- if (m_expandedNameTable.getType(expType) == nodeType) {
- break;
- }
- }
- node = _nextsib(node);
- }
- }
-
- if (node == DTM.NULL || node == _startNodeID) {
- _currentNode = NULL;
- return NULL;
- } else {
- _currentNode = _nextsib(node);
- return returnNode(makeNodeHandle(node));
- }
- }
- } // end of TypedPrecedingSiblingIterator
-
- /**
- * Iterator that returns preceding nodes of a given node.
- * This includes the node set {root+1, start-1}, but excludes
- * all ancestors, attributes, and namespace nodes.
- */
- public class PrecedingIterator extends InternalAxisIteratorBase
- {
-
- /** The max ancestors, but it can grow... */
- private final int _maxAncestors = 8;
-
- /**
- * The stack of start node + ancestors up to the root of the tree,
- * which we must avoid.
- */
- protected int[] _stack = new int[_maxAncestors];
-
- /** (not sure yet... -sb) */
- protected int _sp, _oldsp;
-
- protected int _markedsp, _markedNode, _markedDescendant;
-
- /* _currentNode precedes candidates. This is the identity, not the handle! */
-
- /**
- * True if this iterator has a reversed axis.
- *
- * @return true since this iterator is a reversed axis.
- */
- public boolean isReverse()
- {
- return true;
- }
-
- /**
- * Returns a deep copy of this iterator. The cloned iterator is not reset.
- *
- * @return a deep copy of this iterator.
- */
- public DTMAxisIterator cloneIterator()
- {
- _isRestartable = false;
-
- try
- {
- final PrecedingIterator clone = (PrecedingIterator) super.clone();
- final int[] stackCopy = new int[_stack.length];
- System.arraycopy(_stack, 0, stackCopy, 0, _stack.length);
-
- clone._stack = stackCopy;
-
- // return clone.reset();
- return clone;
- }
- catch (CloneNotSupportedException e)
- {
- throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
- }
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- node = makeNodeIdentity(node);
-
- // iterator is not a clone
- int parent, index;
-
- if (_type(node) == DTM.ATTRIBUTE_NODE)
- node = _parent(node);
-
- _startNode = node;
- _stack[index = 0] = node;
-
-
-
- parent=node;
- while ((parent = _parent(parent)) != NULL)
- {
- if (++index == _stack.length)
- {
- final int[] stack = new int[index + 4];
- System.arraycopy(_stack, 0, stack, 0, index);
- _stack = stack;
- }
- _stack[index] = parent;
- }
- if(index>0)
- --index; // Pop actual root node (if not start) back off the stack
-
- _currentNode=_stack[index]; // Last parent before root node
-
- _oldsp = _sp = index;
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- // Bugzilla 8324: We were forgetting to skip Attrs and NS nodes.
- // Also recoded the loop controls for clarity and to flatten out
- // the tail-recursion.
- for(++_currentNode;
- _sp>=0;
- ++_currentNode)
- {
- if(_currentNode < _stack[_sp])
- {
- if(_type(_currentNode) != ATTRIBUTE_NODE &&
- _type(_currentNode) != NAMESPACE_NODE)
- return returnNode(makeNodeHandle(_currentNode));
- }
- else
- --_sp;
- }
- return NULL;
- }
-
- // redefine DTMAxisIteratorBase's reset
-
- /**
- * Resets the iterator to the last start node.
- *
- * @return A DTMAxisIterator, which may or may not be the same as this
- * iterator.
- */
- public DTMAxisIterator reset()
- {
-
- _sp = _oldsp;
-
- return resetPosition();
- }
-
- public void setMark() {
- _markedsp = _sp;
- _markedNode = _currentNode;
- _markedDescendant = _stack[0];
- }
-
- public void gotoMark() {
- _sp = _markedsp;
- _currentNode = _markedNode;
- }
- } // end of PrecedingIterator
-
- /**
- * Iterator that returns preceding nodes of agiven type for a
- * given node. This includes the node set {root+1, start-1}, but
- * excludes all ancestors.
- */
- public final class TypedPrecedingIterator extends PrecedingIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedPrecedingIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public TypedPrecedingIterator(int type)
- {
- _nodeType = type;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- int node = _currentNode;
- int nodeType = _nodeType;
-
- if (nodeType >= DTM.NTYPES) {
- while (true) {
- node = node + 1;
-
- if (_sp < 0) {
- node = NULL;
- break;
- } else if (node >= _stack[_sp]) {
- if (--_sp < 0) {
- node = NULL;
- break;
- }
- } else if (_exptype(node) == nodeType) {
- break;
- }
- }
- } else {
- int expType;
-
- while (true) {
- node = node + 1;
-
- if (_sp < 0) {
- node = NULL;
- break;
- } else if (node >= _stack[_sp]) {
- if (--_sp < 0) {
- node = NULL;
- break;
- }
- } else {
- expType = _exptype(node);
- if (expType < DTM.NTYPES) {
- if (expType == nodeType) {
- break;
- }
- } else {
- if (m_expandedNameTable.getType(expType) == nodeType) {
- break;
- }
- }
- }
- }
- }
-
- _currentNode = node;
-
- return (node == NULL) ? NULL : returnNode(makeNodeHandle(node));
- }
- } // end of TypedPrecedingIterator
-
- /**
- * Iterator that returns following nodes of for a given node.
- */
- public class FollowingIterator extends InternalAxisIteratorBase
- {
- DTMAxisTraverser m_traverser; // easier for now
-
- public FollowingIterator()
- {
- m_traverser = getAxisTraverser(Axis.FOLLOWING);
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- _startNode = node;
-
- // ?? -sb
- // find rightmost descendant (or self)
- // int current;
- // while ((node = getLastChild(current = node)) != NULL){}
- // _currentNode = current;
- _currentNode = m_traverser.first(node);
-
- // _currentNode precedes possible following(node) nodes
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- int node = _currentNode;
-
- _currentNode = m_traverser.next(_startNode, _currentNode);
-
- return returnNode(node);
- }
- } // end of FollowingIterator
-
- /**
- * Iterator that returns following nodes of a given type for a given node.
- */
- public final class TypedFollowingIterator extends FollowingIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedFollowingIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public TypedFollowingIterator(int type)
- {
- _nodeType = type;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- int node;
-
- do{
- node = _currentNode;
-
- _currentNode = m_traverser.next(_startNode, _currentNode);
-
- }
- while (node != DTM.NULL
- && (getExpandedTypeID(node) != _nodeType && getNodeType(node) != _nodeType));
-
- return (node == DTM.NULL ? DTM.NULL :returnNode(node));
- }
- } // end of TypedFollowingIterator
-
- /**
- * Iterator that returns the ancestors of a given node in document
- * order. (NOTE! This was changed from the XSLTC code!)
- */
- public class AncestorIterator extends InternalAxisIteratorBase
- {
- com.sun.org.apache.xml.internal.utils.NodeVector m_ancestors =
- new com.sun.org.apache.xml.internal.utils.NodeVector();
-
- int m_ancestorsPos;
-
- int m_markedPos;
-
- /** The real start node for this axes, since _startNode will be adjusted. */
- int m_realStartNode;
-
- /**
- * Get start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @return The root node of the iteration.
- */
- public int getStartNode()
- {
- return m_realStartNode;
- }
-
- /**
- * True if this iterator has a reversed axis.
- *
- * @return true since this iterator is a reversed axis.
- */
- public final boolean isReverse()
- {
- return true;
- }
-
- /**
- * Returns a deep copy of this iterator. The cloned iterator is not reset.
- *
- * @return a deep copy of this iterator.
- */
- public DTMAxisIterator cloneIterator()
- {
- _isRestartable = false; // must set to false for any clone
-
- try
- {
- final AncestorIterator clone = (AncestorIterator) super.clone();
-
- clone._startNode = _startNode;
-
- // return clone.reset();
- return clone;
- }
- catch (CloneNotSupportedException e)
- {
- throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported.");
- }
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- m_realStartNode = node;
-
- if (_isRestartable)
- {
- int nodeID = makeNodeIdentity(node);
-
- if (!_includeSelf && node != DTM.NULL) {
- nodeID = _parent(nodeID);
- node = makeNodeHandle(nodeID);
- }
-
- _startNode = node;
-
- while (nodeID != END) {
- m_ancestors.addElement(node);
- nodeID = _parent(nodeID);
- node = makeNodeHandle(nodeID);
- }
- m_ancestorsPos = m_ancestors.size()-1;
-
- _currentNode = (m_ancestorsPos>=0)
- ? m_ancestors.elementAt(m_ancestorsPos)
- : DTM.NULL;
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Resets the iterator to the last start node.
- *
- * @return A DTMAxisIterator, which may or may not be the same as this
- * iterator.
- */
- public DTMAxisIterator reset()
- {
-
- m_ancestorsPos = m_ancestors.size()-1;
-
- _currentNode = (m_ancestorsPos>=0) ? m_ancestors.elementAt(m_ancestorsPos)
- : DTM.NULL;
-
- return resetPosition();
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- int next = _currentNode;
-
- int pos = --m_ancestorsPos;
-
- _currentNode = (pos >= 0) ? m_ancestors.elementAt(m_ancestorsPos)
- : DTM.NULL;
-
- return returnNode(next);
- }
-
- public void setMark() {
- m_markedPos = m_ancestorsPos;
- }
-
- public void gotoMark() {
- m_ancestorsPos = m_markedPos;
- _currentNode = m_ancestorsPos>=0 ? m_ancestors.elementAt(m_ancestorsPos)
- : DTM.NULL;
- }
- } // end of AncestorIterator
-
- /**
- * Typed iterator that returns the ancestors of a given node.
- */
- public final class TypedAncestorIterator extends AncestorIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedAncestorIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public TypedAncestorIterator(int type)
- {
- _nodeType = type;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- m_realStartNode = node;
-
- if (_isRestartable)
- {
- int nodeID = makeNodeIdentity(node);
- int nodeType = _nodeType;
-
- if (!_includeSelf && node != DTM.NULL) {
- nodeID = _parent(nodeID);
- }
-
- _startNode = node;
-
- if (nodeType >= DTM.NTYPES) {
- while (nodeID != END) {
- int eType = _exptype(nodeID);
-
- if (eType == nodeType) {
- m_ancestors.addElement(makeNodeHandle(nodeID));
- }
- nodeID = _parent(nodeID);
- }
- } else {
- while (nodeID != END) {
- int eType = _exptype(nodeID);
-
- if ((eType >= DTM.NTYPES
- && m_expandedNameTable.getType(eType) == nodeType)
- || (eType < DTM.NTYPES && eType == nodeType)) {
- m_ancestors.addElement(makeNodeHandle(nodeID));
- }
- nodeID = _parent(nodeID);
- }
- }
- m_ancestorsPos = m_ancestors.size()-1;
-
- _currentNode = (m_ancestorsPos>=0)
- ? m_ancestors.elementAt(m_ancestorsPos)
- : DTM.NULL;
-
- return resetPosition();
- }
-
- return this;
- }
- } // end of TypedAncestorIterator
-
- /**
- * Iterator that returns the descendants of a given node.
- */
- public class DescendantIterator extends InternalAxisIteratorBase
- {
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isRestartable)
- {
- node = makeNodeIdentity(node);
- _startNode = node;
-
- if (_includeSelf)
- node--;
-
- _currentNode = node;
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Tell if this node identity is a descendant. Assumes that
- * the node info for the element has already been obtained.
- *
- * This one-sided test works only if the parent has been
- * previously tested and is known to be a descendent. It fails if
- * the parent is the _startNode's next sibling, or indeed any node
- * that follows _startNode in document order. That may suffice
- * for this iterator, but it's not really an isDescendent() test.
- * %REVIEW% rename?
- *
- * @param identity The index number of the node in question.
- * @return true if the index is a descendant of _startNode.
- */
- protected boolean isDescendant(int identity)
- {
- return (_parent(identity) >= _startNode) || (_startNode == identity);
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- if (_startNode == NULL) {
- return NULL;
- }
-
- if (_includeSelf && (_currentNode + 1) == _startNode)
- return returnNode(makeNodeHandle(++_currentNode)); // | m_dtmIdent);
-
- int node = _currentNode;
- int type;
-
- do {
- node++;
- type = _type(node);
-
- if (NULL == type ||!isDescendant(node)) {
- _currentNode = NULL;
- return END;
- }
- } while(ATTRIBUTE_NODE == type || TEXT_NODE == type
- || NAMESPACE_NODE == type);
-
- _currentNode = node;
- return returnNode(makeNodeHandle(node)); // make handle.
- }
-
- /**
- * Reset.
- *
- */
- public DTMAxisIterator reset()
- {
-
- final boolean temp = _isRestartable;
-
- _isRestartable = true;
-
- setStartNode(makeNodeHandle(_startNode));
-
- _isRestartable = temp;
-
- return this;
- }
-
- } // end of DescendantIterator
-
- /**
- * Typed iterator that returns the descendants of a given node.
- */
- public final class TypedDescendantIterator extends DescendantIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedDescendantIterator
- *
- *
- * @param nodeType Extended type ID being requested.
- */
- public TypedDescendantIterator(int nodeType)
- {
- _nodeType = nodeType;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
- int node;
- int type;
-
- if (_startNode == NULL) {
- return NULL;
- }
-
- node = _currentNode;
-
- do
- {
- node++;
- type = _type(node);
-
- if (NULL == type ||!isDescendant(node)) {
- _currentNode = NULL;
- return END;
- }
- }
- while (type != _nodeType && _exptype(node) != _nodeType);
-
- _currentNode = node;
- return returnNode(makeNodeHandle(node));
- }
- } // end of TypedDescendantIterator
-
- /**
- * Iterator that returns the descendants of a given node.
- * I'm not exactly clear about this one... -sb
- */
- public class NthDescendantIterator extends DescendantIterator
- {
-
- /** The current nth position. */
- int _pos;
-
- /**
- * Constructor NthDescendantIterator
- *
- *
- * @param pos The nth position being requested.
- */
- public NthDescendantIterator(int pos)
- {
- _pos = pos;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- // I'm not exactly clear yet what this is doing... -sb
- int node;
-
- while ((node = super.next()) != END)
- {
- node = makeNodeIdentity(node);
-
- int parent = _parent(node);
- int child = _firstch(parent);
- int pos = 0;
-
- do
- {
- int type = _type(child);
-
- if (ELEMENT_NODE == type)
- pos++;
- }
- while ((pos < _pos) && (child = _nextsib(child)) != END);
-
- if (node == child)
- return node;
- }
-
- return (END);
- }
- } // end of NthDescendantIterator
-
- /**
- * Class SingletonIterator.
- */
- public class SingletonIterator extends InternalAxisIteratorBase
- {
-
- /** (not sure yet what this is. -sb) (sc & sb remove final to compile in JDK 1.1.8) */
- private boolean _isConstant;
-
- /**
- * Constructor SingletonIterator
- *
- */
- public SingletonIterator()
- {
- this(Integer.MIN_VALUE, false);
- }
-
- /**
- * Constructor SingletonIterator
- *
- *
- * @param node The node handle to return.
- */
- public SingletonIterator(int node)
- {
- this(node, false);
- }
-
- /**
- * Constructor SingletonIterator
- *
- *
- * @param node the node handle to return.
- * @param constant (Not sure what this is yet. -sb)
- */
- public SingletonIterator(int node, boolean constant)
- {
- _currentNode = _startNode = node;
- _isConstant = constant;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node)
- {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE)
- node = getDocument();
- if (_isConstant)
- {
- _currentNode = _startNode;
-
- return resetPosition();
- }
- else if (_isRestartable)
- {
- if (_currentNode == Integer.MIN_VALUE)
- {
- _currentNode = _startNode = node;
- }
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Resets the iterator to the last start node.
- *
- * @return A DTMAxisIterator, which may or may not be the same as this
- * iterator.
- */
- public DTMAxisIterator reset()
- {
-
- if (_isConstant)
- {
- _currentNode = _startNode;
-
- return resetPosition();
- }
- else
- {
- final boolean temp = _isRestartable;
-
- _isRestartable = true;
-
- setStartNode(_startNode);
-
- _isRestartable = temp;
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- final int result = _currentNode;
-
- _currentNode = END;
-
- return returnNode(result);
- }
- } // end of SingletonIterator
-
- /**
- * Iterator that returns a given node only if it is of a given type.
- */
- public final class TypedSingletonIterator extends SingletonIterator
- {
-
- /** The extended type ID that was requested. */
- private final int _nodeType;
-
- /**
- * Constructor TypedSingletonIterator
- *
- *
- * @param nodeType The extended type ID being requested.
- */
- public TypedSingletonIterator(int nodeType)
- {
- _nodeType = nodeType;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next()
- {
-
- //final int result = super.next();
- final int result = _currentNode;
- int nodeType = _nodeType;
-
- _currentNode = END;
-
- if (nodeType >= DTM.NTYPES) {
- if (getExpandedTypeID(result) == nodeType) {
- return returnNode(result);
- }
- } else {
- if (getNodeType(result) == nodeType) {
- return returnNode(result);
- }
- }
-
- return NULL;
- }
- } // end of TypedSingletonIterator
- }