📄 unionpathiterator.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: UnionPathIterator.java,v 1.2.4.1 2005/09/14 19:43:25 jeffsuttor Exp $ */package com.sun.org.apache.xpath.internal.axes;import com.sun.org.apache.xml.internal.dtm.Axis;import com.sun.org.apache.xml.internal.dtm.DTM;import com.sun.org.apache.xml.internal.dtm.DTMIterator;import com.sun.org.apache.xpath.internal.Expression;import com.sun.org.apache.xpath.internal.ExpressionOwner;import com.sun.org.apache.xpath.internal.XPathVisitor;import com.sun.org.apache.xpath.internal.compiler.Compiler;import com.sun.org.apache.xpath.internal.compiler.OpCodes;/** * This class extends NodeSetDTM, which implements DTMIterator, * and fetches nodes one at a time in document order based on a XPath * <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>. * As each node is iterated via nextNode(), the node is also stored * in the NodeVector, so that previousNode() can easily be done. * @xsl.usage advanced */public class UnionPathIterator extends LocPathIterator implements Cloneable, DTMIterator, java.io.Serializable, PathComponent{ static final long serialVersionUID = -3910351546843826781L; /** * Constructor to create an instance which you can add location paths to. */ public UnionPathIterator() { super(); // m_mutable = false; // m_cacheNodes = false; m_iterators = null; m_exprs = null; } /** * 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) { super.setRoot(context, environment); try { if (null != m_exprs) { int n = m_exprs.length; DTMIterator newIters[] = new DTMIterator[n]; for (int i = 0; i < n; i++) { DTMIterator iter = m_exprs[i].asIterator(m_execContext, context); newIters[i] = iter; iter.nextNode(); } m_iterators = newIters; } } catch(Exception e) { throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(e); } } /** * Add an iterator to the union list. * * @param expr non-null reference to a location path iterator. */ public void addIterator(DTMIterator expr) { // Increase array size by only 1 at a time. Fix this // if it looks to be a problem. if (null == m_iterators) { m_iterators = new DTMIterator[1]; m_iterators[0] = expr; } else { DTMIterator[] exprs = m_iterators; int len = m_iterators.length; m_iterators = new DTMIterator[len + 1]; System.arraycopy(exprs, 0, m_iterators, 0, len); m_iterators[len] = expr; } expr.nextNode(); if(expr instanceof Expression) ((Expression)expr).exprSetParent(this); } /** * 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 && null != m_iterators){ int n = m_iterators.length; for(int i = 0; i < n; i++) { m_iterators[i].detach(); } m_iterators = null; } } /** * Create a UnionPathIterator object, including creation * of location path iterators from the opcode list, and call back * into the Compiler to create predicate expressions. * * @param compiler The Compiler which is creating * this expression. * @param opPos The position of this iterator in the * opcode list from the compiler. * * @throws javax.xml.transform.TransformerException */ public UnionPathIterator(Compiler compiler, int opPos) throws javax.xml.transform.TransformerException { super(); opPos = compiler.getFirstChildPos(opPos); loadLocationPaths(compiler, opPos, 0); } /** * This will return an iterator capable of handling the union of paths given. * * @param compiler The Compiler which is creating * this expression. * @param opPos The position of this iterator in the * opcode list from the compiler. * * @return Object that is derived from LocPathIterator. * * @throws javax.xml.transform.TransformerException */ public static LocPathIterator createUnionIterator(Compiler compiler, int opPos) throws javax.xml.transform.TransformerException { // For the moment, I'm going to first create a full UnionPathIterator, and // then see if I can reduce it to a UnionChildIterator. It would obviously // be more effecient to just test for the conditions for a UnionChildIterator, // and then create that directly. UnionPathIterator upi = new UnionPathIterator(compiler, opPos); int nPaths = upi.m_exprs.length; boolean isAllChildIterators = true; for(int i = 0; i < nPaths; i++) { LocPathIterator lpi = upi.m_exprs[i]; if(lpi.getAxis() != Axis.CHILD) { isAllChildIterators = false; break; } else { // check for positional predicates or position function, which won't work. if(HasPositionalPredChecker.check(lpi)) { isAllChildIterators = false; break; } } } if(isAllChildIterators) { UnionChildIterator uci = new UnionChildIterator(); for(int i = 0; i < nPaths; i++) { PredicatedNodeTest lpi = upi.m_exprs[i]; // I could strip the lpi down to a pure PredicatedNodeTest, but // I don't think it's worth it. Note that the test can be used // as a static object... so it doesn't have to be cloned. uci.addNodeTest(lpi); } return uci; } else return upi; } /** * Get the analysis bits for this walker, as defined in the WalkerFactory. * @return One of WalkerFactory#BIT_DESCENDANT, etc. */ public int getAnalysisBits() { int bits = 0; if (m_exprs != null) { int n = m_exprs.length; for (int i = 0; i < n; i++) { int bit = m_exprs[i].getAnalysisBits(); bits |= bit; } } return bits; } /** * Read the object from a serialization stream. * * @param stream Input stream to read from * * @throws java.io.IOException * @throws javax.xml.transform.TransformerException */ private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, javax.xml.transform.TransformerException { try { stream.defaultReadObject(); m_clones = new IteratorPool(this); } catch (ClassNotFoundException cnfe) { throw new javax.xml.transform.TransformerException(cnfe); } } /** * 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 { UnionPathIterator clone = (UnionPathIterator) super.clone(); if (m_iterators != null) { int n = m_iterators.length; clone.m_iterators = new DTMIterator[n]; for (int i = 0; i < n; i++) { clone.m_iterators[i] = (DTMIterator)m_iterators[i].clone(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -