sax2dtm2.java
来自「JAVA 所有包」· Java 代码 · 共 2,403 行 · 第 1/5 页
JAVA
2,403 行
/* * Copyright 1999-2005 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: SAX2DTM2.java,v 1.2.4.1 2005/09/15 08:15:12 suresh_emailid Exp $ */package com.sun.org.apache.xml.internal.dtm.ref.sax2dtm;import com.sun.org.apache.xml.internal.dtm.*;import com.sun.org.apache.xml.internal.dtm.ref.*;import com.sun.org.apache.xml.internal.utils.FastStringBuffer;import com.sun.org.apache.xml.internal.utils.XMLString;import com.sun.org.apache.xml.internal.utils.XMLStringDefault;import com.sun.org.apache.xml.internal.utils.XMLStringFactory;import com.sun.org.apache.xml.internal.res.XMLMessages;import com.sun.org.apache.xml.internal.res.XMLErrorResources;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import javax.xml.transform.Source;import java.util.Vector;import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector;import org.xml.sax.*;/** * SAX2DTM2 is an optimized version of SAX2DTM which is used in non-incremental situation. * It is used as the super class of the XSLTC SAXImpl. Many of the interfaces in SAX2DTM * and DTMDefaultBase are overridden in SAX2DTM2 in order to allow fast, efficient * access to the DTM model. Some nested iterators in DTMDefaultBaseIterators * are also overridden in SAX2DTM2 for performance reasons. * <p> * Performance is the biggest consideration in the design of SAX2DTM2. To make the code most * efficient, the incremental support is dropped in SAX2DTM2, which means that you should not * use it in incremental situation. To reduce the overhead of pulling data from the DTM model, * a few core interfaces in SAX2DTM2 have direct access to the internal arrays of the * SuballocatedIntVectors. * <p> * The design of SAX2DTM2 may limit its extensibilty. If you have a reason to extend the * SAX2DTM model, please extend from SAX2DTM instead of this class. * <p> * TODO: This class is currently only used by XSLTC. We need to investigate the possibility * of also using it in Xalan-J Interpretive. Xalan's performance is likely to get an instant * boost if we use SAX2DTM2 instead of SAX2DTM in non-incremental case. * <p> * %MK% The code in this class is critical to the XSLTC_DTM performance. Be very careful * when making changes here! */public class SAX2DTM2 extends SAX2DTM{ /**************************************************************** * Optimized version of the nested iterators ****************************************************************/ /** * 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. * <p> * 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 : _firstch2(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 = _nextsib2(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 = DTM.NULL; /** * 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; if (node != DTM.NULL) _currentNode = _parent2(makeNodeIdentity(node)); else _currentNode = DTM.NULL; 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 (result == END) return DTM.NULL; // %OPT% The most common case is handled first. if (_nodeType == NULL) { _currentNode = END; return returnNode(makeNodeHandle(result)); } else if (_nodeType >= DTM.NTYPES) { if (_nodeType == _exptype2(result)) { _currentNode = END; return returnNode(makeNodeHandle(result)); } } else { if (_nodeType == _type2(result)) { _currentNode = END; return returnNode(makeNodeHandle(result)); } } return DTM.NULL; } } // 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 : _firstch2(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 node = _currentNode; if (node == DTM.NULL) return DTM.NULL; final int nodeType = _nodeType; if (nodeType != DTM.ELEMENT_NODE) { while (node != DTM.NULL && _exptype2(node) != nodeType) { node = _nextsib2(node); } } // %OPT% If the nodeType is element (matching child::*), we only // need to compare the expType with DTM.NTYPES. A child node of // an element can be either an element, text, comment or // processing instruction node. Only element node has an extended // type greater than or equal to DTM.NTYPES. else { int eType; while (node != DTM.NULL) { eType = _exptype2(node); if (eType >= DTM.NTYPES) break; else node = _nextsib2(node); } } if (node == DTM.NULL) { _currentNode = DTM.NULL; return DTM.NULL; } else { _currentNode = _nextsib2(node); return returnNode(makeNodeHandle(node)); } } /** * Return the node at the given position. */ public int getNodeByPosition(int position) { if (position <= 0) return DTM.NULL; int node = _currentNode; int pos = 0; final int nodeType = _nodeType; if (nodeType != DTM.ELEMENT_NODE) { while (node != DTM.NULL) { if (_exptype2(node) == nodeType) { pos++; if (pos == position) return makeNodeHandle(node); } node = _nextsib2(node); } return NULL; } else { while (node != DTM.NULL) { if (_exptype2(node) >= DTM.NTYPES) { pos++; if (pos == position) return makeNodeHandle(node); } node = _nextsib2(node); } return NULL; } } } // end of TypedChildrenIterator /** * 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; final int node = _startNode; int expType = _exptype2(makeNodeIdentity(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_extendedTypes[expType].getNodeType() == _nodeType) { return returnNode(node); } } } return NULL; } } // end of TypedRootIterator /** * 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 : _nextsib2(_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; final int nodeType = _nodeType; if (nodeType != DTM.ELEMENT_NODE) { while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) != nodeType) {} } else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?