onestepiterator.java
来自「java jdk 1.4的源码」· Java 代码 · 共 249 行
JAVA
249 行
package org.apache.xpath.axes;import javax.xml.transform.TransformerException;import org.apache.xml.dtm.DTM;import org.apache.xml.dtm.DTMAxisIterator;import org.apache.xml.dtm.DTMFilter;import org.apache.xml.dtm.DTMIterator;import org.apache.xpath.Expression;import org.apache.xpath.XPathContext;import org.apache.xpath.compiler.Compiler;/** * <meta name="usage" content="advanced"/> * This class implements a general iterator for * those LocationSteps with only one step, and perhaps a predicate. * @see org.apache.xpath.axes.WalkerFactory#newLocPathIterator */public class OneStepIterator extends ChildTestIterator{ /** The traversal axis from where the nodes will be filtered. */ protected int m_axis = -1; /** The DTM inner traversal class, that corresponds to the super axis. */ protected DTMAxisIterator m_iterator; /** * Create a OneStepIterator object. * * @param compiler A reference to the Compiler that contains the op map. * @param opPos The position within the op map, which contains the * location path expression for this itterator. * * @throws javax.xml.transform.TransformerException */ OneStepIterator(Compiler compiler, int opPos, int analysis) throws javax.xml.transform.TransformerException { super(compiler, opPos, analysis); int firstStepPos = compiler.getFirstChildPos(opPos); m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos); } /** * Create a OneStepIterator object. * * @param iterator The DTM iterator which this iterator will use. * @param axis One of Axis.Child, etc., or -1 if the axis is unknown. * * @throws javax.xml.transform.TransformerException */ public OneStepIterator(DTMAxisIterator iterator, int axis) throws javax.xml.transform.TransformerException { super(null); m_iterator = iterator; m_axis = axis; int whatToShow = DTMFilter.SHOW_ALL; initNodeTest(whatToShow); } /** * Initialize the context values for this expression * after it is cloned. * * @param execContext The XPath runtime context for this * transformation. */ public void setRoot(int context, Object environment) { super.setRoot(context, environment); if(m_axis > -1) m_iterator = m_cdtm.getAxisIterator(m_axis); m_iterator.setStartNode(m_context); } /** * Get the next node via getFirstAttribute && getNextAttribute. */ protected int getNextNode() { return m_lastFetched = m_iterator.next(); } /** * Get a cloned iterator. * * @return A new iterator that can be used without mutating this one. * * @throws CloneNotSupportedException */ public Object clone() throws CloneNotSupportedException { // Do not access the location path itterator during this operation! OneStepIterator clone = (OneStepIterator) super.clone(); if(m_iterator != null) { clone.m_iterator = m_iterator.cloneIterator(); } return clone; } /** * 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 { OneStepIterator clone = (OneStepIterator) super.cloneWithReset(); clone.m_iterator = m_iterator; return clone; } /** * Tells if this is a reverse axes. Overrides AxesWalker#isReverseAxes. * * @return true for this class. */ public boolean isReverseAxes() { return m_iterator.isReverse(); } /** * Get the current sub-context position. In order to do the * reverse axes count, for the moment this re-searches the axes * up to the predicate. An optimization on this is to cache * the nodes searched, but, for the moment, this case is probably * rare enough that the added complexity isn't worth it. * * @param predicateIndex The predicate index of the proximity position. * * @return The pridicate index, or -1. */ protected int getProximityPosition(int predicateIndex) { if(!isReverseAxes()) return super.getProximityPosition(predicateIndex); // A negative predicate index seems to occur with // (preceding-sibling::*|following-sibling::*)/ancestor::*[position()]/*[position()] // -sb if(predicateIndex < 0) return -1; if (m_proximityPositions[predicateIndex] <= 0) { XPathContext xctxt = getXPathContext(); try { OneStepIterator clone = (OneStepIterator) this.clone(); int root = getRoot(); xctxt.pushCurrentNode(root); clone.setRoot(root, xctxt); // clone.setPredicateCount(predicateIndex); clone.m_predCount = predicateIndex; // Count 'em all int count = 1; int next; while (DTM.NULL != (next = clone.nextNode())) { count++; } m_proximityPositions[predicateIndex] += count; } catch (CloneNotSupportedException cnse) { // can't happen } finally { xctxt.popCurrentNode(); } } return m_proximityPositions[predicateIndex]; } /** * Count backwards one proximity position. * * @param i The predicate index. */ protected void countProximityPosition(int i) { if(!isReverseAxes()) super.countProximityPosition(i); else if (i < m_proximityPositions.length) m_proximityPositions[i]--; } /** * Reset the iterator. */ public void reset() { super.reset(); if(null != m_iterator) m_iterator.reset(); } /** * 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 m_axis; } /** * @see Expression#deepEquals(Expression) */ public boolean deepEquals(Expression expr) { if(!super.deepEquals(expr)) return false; if(m_axis != ((OneStepIterator)expr).m_axis) return false; return true; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?