dtmdefaultbaseiterators.java
来自「JAVA 所有包」· Java 代码 · 共 2,195 行 · 第 1/4 页
JAVA
2,195 行
/* * 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.2.4.1 2005/09/15 08:15:00 suresh_emailid 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;import com.sun.org.apache.xalan.internal.xsltc.dom.NodeCounter;/** * 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 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 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.getNames(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.getNames(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(); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?