/** * Get a cloned WalkingIterator 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 { WalkingIterator clone = (WalkingIterator) super.clone(); // clone.m_varStackPos = this.m_varStackPos; // clone.m_varStackContext = this.m_varStackContext; if (null != m_firstWalker) { clone.m_firstWalker = m_firstWalker.cloneDeep(clone, null); } return clone; }
/** @see ExpressionOwner#setExpression(Expression) */ public void setExpression(Expression exp) { if (!(exp instanceof LocPathIterator)) { // Yuck. Need FilterExprIter. Or make it so m_exprs can be just // plain expressions? WalkingIterator wi = new WalkingIterator(getPrefixResolver()); FilterExprWalker few = new FilterExprWalker(wi); wi.setFirstWalker(few); few.setInnerExpression(exp); wi.exprSetParent(UnionPathIterator.this); few.exprSetParent(wi); exp.exprSetParent(few); exp = wi; } else exp.exprSetParent(UnionPathIterator.this); m_exprs[m_index] = (LocPathIterator) exp; }
/** * Initialize the location path iterators. Recursive. * * @param compiler The Compiler which is creating this expression. * @param opPos The position of this iterator in the opcode list from the compiler. * @param count The insert position of the iterator. * @throws javax.xml.transform.TransformerException */ protected void loadLocationPaths(Compiler compiler, int opPos, int count) throws javax.xml.transform.TransformerException { // TODO: Handle unwrapped FilterExpr int steptype = compiler.getOp(opPos); if (steptype == OpCodes.OP_LOCATIONPATH) { loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1); m_exprs[count] = createDTMIterator(compiler, opPos); m_exprs[count].exprSetParent(this); } else { // Have to check for unwrapped functions, which the LocPathIterator // doesn't handle. switch (steptype) { case OpCodes.OP_VARIABLE: case OpCodes.OP_EXTFUNCTION: case OpCodes.OP_FUNCTION: case OpCodes.OP_GROUP: loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1); WalkingIterator iter = new WalkingIterator(compiler.getNamespaceContext()); iter.exprSetParent(this); if (compiler.getLocationPathDepth() <= 0) iter.setIsTopLevel(true); iter.m_firstWalker = new com.sun.org.apache.xpath.internal.axes.FilterExprWalker(iter); iter.m_firstWalker.init(compiler, opPos, steptype); m_exprs[count] = iter; break; default: m_exprs = new LocPathIterator[count]; } } }
/** * Get the index of the last node that can be itterated to. * * @param xctxt XPath runtime context. * @return the index of the last node that can be itterated to. */ public int getLastPos(XPathContext xctxt) { int pos = getProximityPosition(); AxesWalker walker; try { walker = (AxesWalker) clone(); } catch (CloneNotSupportedException cnse) { return -1; } walker.setPredicateCount(walker.getPredicateCount() - 1); walker.setNextWalker(null); walker.setPrevWalker(null); WalkingIterator lpi = wi(); AxesWalker savedWalker = lpi.getLastUsedWalker(); try { lpi.setLastUsedWalker(walker); int next; while (DTM.NULL != (next = walker.nextNode())) { pos++; } // TODO: Should probably save this in the iterator. } finally { lpi.setLastUsedWalker(savedWalker); } // System.out.println("pos: "+pos); return pos; }
/** * Do a deep clone of this walker, including next and previous walkers. If the this AxesWalker is * on the clone list, don't clone but return the already cloned version. * * @param cloneOwner non-null reference to the cloned location path iterator to which this clone * will be added. * @param cloneList non-null vector of sources in odd elements, and the corresponding clones in * even vectors. * @return non-null clone, which may be a new clone, or may be a clone contained on the cloneList. */ AxesWalker cloneDeep(WalkingIterator cloneOwner, Vector cloneList) throws CloneNotSupportedException { AxesWalker clone = findClone(this, cloneList); if (null != clone) return clone; clone = (AxesWalker) this.clone(); clone.setLocPathIterator(cloneOwner); if (null != cloneList) { cloneList.addElement(this); cloneList.addElement(clone); } if (wi().m_lastUsedWalker == this) cloneOwner.m_lastUsedWalker = clone; if (null != m_nextWalker) clone.m_nextWalker = m_nextWalker.cloneDeep(cloneOwner, cloneList); // If you don't check for the cloneList here, you'll go into an // recursive infinate loop. if (null != cloneList) { if (null != m_prevWalker) clone.m_prevWalker = m_prevWalker.cloneDeep(cloneOwner, cloneList); } else { if (null != m_nextWalker) clone.m_nextWalker.m_prevWalker = clone; } return clone; }