📄 nodesetdtm.java
字号:
/* * 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: NodeSetDTM.java,v 1.2.4.2 2005/09/14 20:30:06 jeffsuttor Exp $ */package com.sun.org.apache.xpath.internal;import com.sun.org.apache.xalan.internal.res.XSLMessages;import com.sun.org.apache.xml.internal.dtm.DTM;import com.sun.org.apache.xml.internal.dtm.DTMFilter;import com.sun.org.apache.xml.internal.dtm.DTMIterator;import com.sun.org.apache.xml.internal.dtm.DTMManager;import com.sun.org.apache.xml.internal.utils.NodeVector;import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.w3c.dom.traversal.NodeIterator;/** * <p>The NodeSetDTM class can act as either a NodeVector, * NodeList, or NodeIterator. However, in order for it to * act as a NodeVector or NodeList, it's required that * setShouldCacheNodes(true) be called before the first * nextNode() is called, in order that nodes can be added * as they are fetched. Derived classes that implement iterators * must override runTo(int index), in order that they may * run the iteration to the given index. </p> * * <p>Note that we directly implement the DOM's NodeIterator * interface. We do not emulate all the behavior of the * standard NodeIterator. In particular, we do not guarantee * to present a "live view" of the document ... but in XSLT, * the source document should never be mutated, so this should * never be an issue.</p> * * <p>Thought: Should NodeSetDTM really implement NodeList and NodeIterator, * or should there be specific subclasses of it which do so? The * advantage of doing it all here is that all NodeSetDTMs will respond * to the same calls; the disadvantage is that some of them may return * less-than-enlightening results when you do so.</p> * @xsl.usage advanced */public class NodeSetDTM extends NodeVector implements /* NodeList, NodeIterator, */ DTMIterator, Cloneable{ static final long serialVersionUID = 7686480133331317070L; /** * Create an empty nodelist. */ public NodeSetDTM(DTMManager dtmManager) { super(); m_manager = dtmManager; } /** * Create an empty, using the given block size. * * @param blocksize Size of blocks to allocate * @param dummy pass zero for right now... */ public NodeSetDTM(int blocksize, int dummy, DTMManager dtmManager) { super(blocksize); m_manager = dtmManager; } // %TBD%// /**// * Create a NodeSetDTM, and copy the members of the// * given nodelist into it.// *// * @param nodelist List of Nodes to be made members of the new set.// */// public NodeSetDTM(NodeList nodelist)// {//// super();//// addNodes(nodelist);// } /** * Create a NodeSetDTM, and copy the members of the * given NodeSetDTM into it. * * @param nodelist Set of Nodes to be made members of the new set. */ public NodeSetDTM(NodeSetDTM nodelist) { super(); m_manager = nodelist.getDTMManager(); m_root = nodelist.getRoot(); addNodes((DTMIterator) nodelist); } /** * Create a NodeSetDTM, and copy the members of the * given DTMIterator into it. * * @param ni Iterator which yields Nodes to be made members of the new set. */ public NodeSetDTM(DTMIterator ni) { super(); m_manager = ni.getDTMManager(); m_root = ni.getRoot(); addNodes(ni); } /** * Create a NodeSetDTM, and copy the members of the * given DTMIterator into it. * * @param iterator Iterator which yields Nodes to be made members of the new set. */ public NodeSetDTM(NodeIterator iterator, XPathContext xctxt) { super(); Node node; m_manager = xctxt.getDTMManager(); while (null != (node = iterator.nextNode())) { int handle = xctxt.getDTMHandleFromNode(node); addNodeInDocOrder(handle, xctxt); } } /** * Create a NodeSetDTM, and copy the members of the * given DTMIterator into it. * */ public NodeSetDTM(NodeList nodeList, XPathContext xctxt) { super(); m_manager = xctxt.getDTMManager(); int n = nodeList.getLength(); for (int i = 0; i < n; i++) { Node node = nodeList.item(i); int handle = xctxt.getDTMHandleFromNode(node); // Do not reorder or strip duplicate nodes from the given DOM nodelist addNode(handle); // addNodeInDocOrder(handle, xctxt); } } /** * Create a NodeSetDTM which contains the given Node. * * @param node Single node to be added to the new set. */ public NodeSetDTM(int node, DTMManager dtmManager) { super(); m_manager = dtmManager; addNode(node); } /** * Set the environment in which this iterator operates, which should provide: * a node (the context node... same value as "root" defined below) * a pair of non-zero positive integers (the context position and the context size) * a set of variable bindings * a function library * the set of namespace declarations in scope for the expression. * * <p>At this time the exact implementation of this environment is application * dependent. Probably a proper interface will be created fairly soon.</p> * * @param environment The environment object. */ public void setEnvironment(Object environment) { // no-op } /** * @return The root node of the Iterator, as specified when it was created. * For non-Iterator NodeSetDTMs, this will be null. */ public int getRoot() { if(DTM.NULL == m_root) { if(size() > 0) return item(0); else return DTM.NULL; } else return m_root; } /** * Initialize the context values for this expression * after it is cloned. * * @param context The XPath runtime context for this * transformation. */ public void setRoot(int context, Object environment) { // no-op, I guess... (-sb) } /** * Clone this NodeSetDTM. * At this time, we only expect this to be used with LocPathIterators; * it may not work with other kinds of NodeSetDTMs. * * @return a new NodeSetDTM of the same type, having the same state... * though unless overridden in the subclasses, it may not copy all * the state information. * * @throws CloneNotSupportedException if this subclass of NodeSetDTM * does not support the clone() operation. */ public Object clone() throws CloneNotSupportedException { NodeSetDTM clone = (NodeSetDTM) super.clone(); return clone; } /** * Get a cloned Iterator, and reset its state to the beginning of the * iteration. * * @return a new NodeSetDTM of the same type, having the same state... * except that the reset() operation has been called. * * @throws CloneNotSupportedException if this subclass of NodeSetDTM * does not support the clone() operation. */ public DTMIterator cloneWithReset() throws CloneNotSupportedException { NodeSetDTM clone = (NodeSetDTM) clone(); clone.reset(); return clone; } /** * Reset the iterator. May have no effect on non-iterator Nodesets. */ public void reset() { m_next = 0; } /** * This attribute determines which node types are presented via the * iterator. The available set of constants is defined in the * <code>DTMFilter</code> interface. For NodeSetDTMs, the mask has been * hardcoded to show all nodes except EntityReference nodes, which have * no equivalent in the XPath data model. * * @return integer used as a bit-array, containing flags defined in * the DOM's DTMFilter class. The value will be * <code>SHOW_ALL & ~SHOW_ENTITY_REFERENCE</code>, meaning that * only entity references are suppressed. */ public int getWhatToShow() { return DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE; } /** * The filter object used to screen nodes. Filters are applied to * further reduce (and restructure) the DTMIterator's view of the * document. In our case, we will be using hardcoded filters built * into our iterators... but getFilter() is part of the DOM's * DTMIterator interface, so we have to support it. * * @return null, which is slightly misleading. True, there is no * user-written filter object, but in fact we are doing some very * sophisticated custom filtering. A DOM purist might suggest * returning a placeholder object just to indicate that this is * not going to return all nodes selected by whatToShow. */ public DTMFilter getFilter() { return null; } /** * The value of this flag determines whether the children of entity * reference nodes are visible to the iterator. If false, they will be * skipped over. * <br> To produce a view of the document that has entity references * expanded and does not expose the entity reference node itself, use the * whatToShow flags to hide the entity reference node and set * expandEntityReferences to true when creating the iterator. To produce * a view of the document that has entity reference nodes but no entity * expansion, use the whatToShow flags to show the entity reference node * and set expandEntityReferences to false. * * @return true for all iterators based on NodeSetDTM, meaning that the * contents of EntityRefrence nodes may be returned (though whatToShow * says that the EntityReferences themselves are not shown.) */ public boolean getExpandEntityReferences() { return true; } /** * Get an instance of a DTM that "owns" a node handle. Since a node * iterator may be passed without a DTMManager, this allows the * caller to easily get the DTM using just the iterator. * * @param nodeHandle the nodeHandle. * * @return a non-null DTM reference. */ public DTM getDTM(int nodeHandle) { return m_manager.getDTM(nodeHandle); } /* An instance of the DTMManager. */ DTMManager m_manager; /** * Get an instance of the DTMManager. Since a node * iterator may be passed without a DTMManager, this allows the * caller to easily get the DTMManager using just the iterator. * * @return a non-null DTMManager reference. */ public DTMManager getDTMManager() { return m_manager; } /** * Returns the next node in the set and advances the position of the * iterator in the set. After a DTMIterator is created, the first call * to nextNode() returns the first node in the set. * @return The next <code>Node</code> in the set being iterated over, or * <code>DTM.NULL</code> if there are no more members in that set. * @throws DOMException * INVALID_STATE_ERR: Raised if this method is called after the * <code>detach</code> method was invoked. */ public int nextNode() { if ((m_next) < this.size()) { int next = this.elementAt(m_next); m_next++; return next; } else return DTM.NULL; } /** * Returns the previous node in the set and moves the position of the * iterator backwards in the set. * @return The previous <code>Node</code> in the set being iterated over, * or<code>DTM.NULL</code> if there are no more members in that set. * @throws DOMException * INVALID_STATE_ERR: Raised if this method is called after the * <code>detach</code> method was invoked. * @throws RuntimeException thrown if this NodeSetDTM is not of * a cached type, and hence doesn't know what the previous node was. */ public int previousNode() { if (!m_cacheNodes) throw new RuntimeException( XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_ITERATE, null)); //"This NodeSetDTM can not iterate to a previous node!"); if ((m_next - 1) > 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -