📄 locpathiterator.java
字号:
return m_length; // I'm a bit worried about this one, since it doesn't have the // checks found above. I suspect it's fine. -sb if (m_foundLast) return m_pos; // Create a clone, and count from the current position to the end // of the list, not taking into account the current predicate and // predicates after the current one. int pos = (m_predicateIndex >= 0) ? getProximityPosition() : m_pos; LocPathIterator clone; try { clone = (LocPathIterator) clone(); } catch (CloneNotSupportedException cnse) { return -1; } // We want to clip off the last predicate, but only if we are a sub // context node list, NOT if we are a context list. See pos68 test, // also test against bug4638. if (predCount > 0 && isPredicateTest) { // Don't call setPredicateCount, because it clones and is slower. clone.m_predCount = m_predicateIndex; // The line above used to be: // clone.m_predCount = predCount - 1; // ...which looks like a dumb bug to me. -sb } int next; while (DTM.NULL != (next = clone.nextNode())) { pos++; } if (isPredicateTest && m_predicateIndex < 1) m_length = pos; return pos; } /** * Tells if this NodeSetDTM is "fresh", in other words, if * the first nextNode() that is called will return the * first node in the set. * * @return true of nextNode has not been called. */ public boolean isFresh() { return (m_pos == 0); } /** * 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>null</code> if there are no more members in that set. */ public int previousNode() { throw new RuntimeException( XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_ITERATE, null)); //"This NodeSetDTM can not iterate to a previous node!"); } /** * This attribute determines which node types are presented via the * iterator. The available set of constants is defined in the * <code>NodeFilter</code> interface. * * <p>This is somewhat useless at this time, since it doesn't * really return information that tells what this iterator will * show. It is here only to fullfill the DOM NodeIterator * interface.</p> * * @return For now, always NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_ENTITY_REFERENCE. * @see org.w3c.dom.traversal.NodeIterator */ public int getWhatToShow() { // TODO: ?? return DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE; } /** * The filter used to screen nodes. Not used at this time, * this is here only to fullfill the DOM NodeIterator * interface. * * @return Always null. * @see org.w3c.dom.traversal.NodeIterator */ public DTMFilter getFilter() { return null; } /** * The root node of the Iterator, as specified when it was created. * * @return The "root" of this iterator, which, in XPath terms, * is the node context for this iterator. */ public int getRoot() { return m_context; } /** * 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 Always true, since entity reference nodes are not * visible in the XPath model. */ public boolean getExpandEntityReferences() { return true; } /** Control over whether it is OK for detach to reset the iterator. */ protected boolean m_allowDetach = true; /** * Specify if it's OK for detach to release the iterator for reuse. * * @param allowRelease true if it is OK for detach to release this iterator * for pooling. */ public void allowDetachToRelease(boolean allowRelease) { m_allowDetach = allowRelease; } /** * Detaches the iterator from the set which it iterated over, releasing * any computational resources and placing the iterator in the INVALID * state. After<code>detach</code> has been invoked, calls to * <code>nextNode</code> or<code>previousNode</code> will raise the * exception INVALID_STATE_ERR. */ public void detach() { if(m_allowDetach) { // sb: allow reusing of cached nodes when possible? // m_cachedNodes = null; m_execContext = null; // m_prefixResolver = null; sb: Why would this ever want to be null? m_cdtm = null; m_length = -1; m_pos = 0; m_lastFetched = DTM.NULL; m_context = DTM.NULL; m_currentContextNode = DTM.NULL; m_clones.freeInstance(this); } } /** * Reset the iterator. */ public void reset() { assertion(false, "This iterator can not reset!"); } /** * Get a cloned Iterator that is reset to the beginning * of the query. * * @return A cloned NodeIterator set of the start of the query. * * @throws CloneNotSupportedException */ public DTMIterator cloneWithReset() throws CloneNotSupportedException { LocPathIterator clone;// clone = (LocPathIterator) clone(); clone = (LocPathIterator)m_clones.getInstanceOrThrow(); clone.m_execContext = m_execContext; clone.m_cdtm = m_cdtm; clone.m_context = m_context; clone.m_currentContextNode = m_currentContextNode; clone.m_stackFrame = m_stackFrame; // clone.reset(); return clone; }// /**// * Get a cloned LocPathIterator that holds the same// * position as this iterator.// *// * @return A clone of this iterator that holds the same node position.// *// * @throws CloneNotSupportedException// */// public Object clone() throws CloneNotSupportedException// {//// LocPathIterator clone = (LocPathIterator) super.clone();//// return clone;// } /** * Returns the next node in the set and advances the position of the * iterator in the set. After a NodeIterator 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>null</code> if there are no more members in that set. */ public abstract int nextNode(); /** * Bottleneck the return of a next node, to make returns * easier from nextNode(). * * @param nextNode The next node found, may be null. * * @return The same node that was passed as an argument. */ protected int returnNextNode(int nextNode) { if (DTM.NULL != nextNode) { m_pos++; } m_lastFetched = nextNode; if (DTM.NULL == nextNode) m_foundLast = true; return nextNode; } /** * Return the last fetched node. Needed to support the UnionPathIterator. * * @return The last fetched node, or null if the last fetch was null. */ public int getCurrentNode() { return m_lastFetched; } /** * If an index is requested, NodeSetDTM will call this method * to run the iterator to the index. By default this sets * m_next to the index. If the index argument is -1, this * signals that the iterator should be run to the end. * * @param index The index to run to, or -1 if the iterator * should run to the end. */ public void runTo(int index) { if (m_foundLast || ((index >= 0) && (index <= getCurrentPos()))) return; int n; if (-1 == index) { while (DTM.NULL != (n = nextNode())); } else { while (DTM.NULL != (n = nextNode())) { if (getCurrentPos() >= index) break; } } } /** * Tells if we've found the last node yet. * * @return true if the last nextNode returned null. */ public final boolean getFoundLast() { return m_foundLast; } /** * The XPath execution context we are operating on. * * @return XPath execution context this iterator is operating on, * or null if setRoot has not been called. */ public final XPathContext getXPathContext() { return m_execContext; } /** * The node context for the iterator. * * @return The node context, same as getRoot(). */ public final int getContext() { return m_context; } /** * The node context from where the expression is being * executed from (i.e. for current() support). * * @return The top-level node context of the entire expression. */ public final int getCurrentContextNode() { return m_currentContextNode; } /** * Set the current context node for this iterator. * * @param n Must be a non-null reference to the node context. */ public final void setCurrentContextNode(int n) { m_currentContextNode = n; } // /**// * Set the current context node for this iterator.// *// * @param n Must be a non-null reference to the node context.// */// public void setRoot(int n)// {// m_context = n;// m_cdtm = m_execContext.getDTM(n);// } /** * Return the saved reference to the prefix resolver that * was in effect when this iterator was created. * * @return The prefix resolver or this iterator, which may be null. */ public final PrefixResolver getPrefixResolver() { if(null == m_prefixResolver) { m_prefixResolver = (PrefixResolver)getExpressionOwner(); } return m_prefixResolver; } // /**// * Get the analysis pattern built by the WalkerFactory.// *// * @return The analysis pattern built by the WalkerFactory.// */// int getAnalysis()// {// return m_analysis;// }// /**// * Set the analysis pattern built by the WalkerFactory.// *// * @param a The analysis pattern built by the WalkerFactory.// */// void setAnalysis(int a)// {// m_analysis = a;// } /** * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) */ public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) { if(visitor.visitLocationPath(owner, this)) { visitor.visitStep(owner, this); callPredicateVisitors(visitor); } } //============= State Data ============= /** * The pool for cloned iterators. Iterators need to be cloned * because the hold running state, and thus the original iterator * expression from the stylesheet pool can not be used. */ transient protected IteratorPool m_clones = new IteratorPool(this); /** * The dtm of the context node. Careful about using this... it may not * be the dtm of the current node. */ transient protected DTM m_cdtm; /** * The stack frame index for this iterator. */ transient int m_stackFrame = -1; /** * Value determined at compile time, indicates that this is an * iterator at the top level of the expression, rather than inside * a predicate. * @serial */ private boolean m_isTopLevel = false; /** The last node that was fetched, usually by nextNode. */ transient public int m_lastFetched = DTM.NULL; /** * The context node for this iterator, which doesn't change through * the course of the iteration. */ transient protected int m_context = DTM.NULL; /** * The node context from where the expression is being * executed from (i.e. for current() support). Different * from m_context in that this is the context for the entire * expression, rather than the context for the subexpression. */ transient protected int m_currentContextNode = DTM.NULL; /** * The current position of the context node. */ transient protected int m_pos = 0; transient protected int m_length = -1; /** * Fast access to the current prefix resolver. It isn't really * clear that this is needed. * @serial */ private PrefixResolver m_prefixResolver; /** * The XPathContext reference, needed for execution of many * operations. */ transient protected XPathContext m_execContext; /** * Returns true if all the nodes in the iteration well be returned in document * order. * * @return true as a default. */ public boolean isDocOrdered() { return true; } /** * Returns the axis being iterated, if it is known. * * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple * types. */ public int getAxis() { return -1; }// /**// * The analysis pattern built by the WalkerFactory.// * TODO: Move to LocPathIterator.// * @see com.sun.org.apache.xpath.internal.axes.WalkerFactory// * @serial// */// protected int m_analysis = 0x00000000; /** * @see PredicatedNodeTest#getLastPos(XPathContext) */ public int getLastPos(XPathContext xctxt) { return getLength(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -