14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file 44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information 54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file 64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License. 84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at 94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software 134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and 164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License. 174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: OneStepIterator.java 469314 2006-10-30 23:31:59Z minchau $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xpath.axes; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTM; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMAxisIterator; 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMFilter; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMIterator; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.Expression; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathContext; 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.compiler.Compiler; 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.compiler.OpMap; 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This class implements a general iterator for 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * those LocationSteps with only one step, and perhaps a predicate. 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.axes#LocPathIterator 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @xsl.usage advanced 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class OneStepIterator extends ChildTestIterator 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = 4623710779664998283L; 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The traversal axis from where the nodes will be filtered. */ 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected int m_axis = -1; 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The DTM inner traversal class, that corresponds to the super axis. */ 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected DTMAxisIterator m_iterator; 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Create a OneStepIterator object. 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param compiler A reference to the Compiler that contains the op map. 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param opPos The position within the op map, which contains the 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * location path expression for this itterator. 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson OneStepIterator(Compiler compiler, int opPos, int analysis) 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super(compiler, opPos, analysis); 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int firstStepPos = OpMap.getFirstChildPos(opPos); 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos); 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Create a OneStepIterator object. 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param iterator The DTM iterator which this iterator will use. 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param axis One of Axis.Child, etc., or -1 if the axis is unknown. 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public OneStepIterator(DTMAxisIterator iterator, int axis) 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super(null); 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_iterator = iterator; 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_axis = axis; 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int whatToShow = DTMFilter.SHOW_ALL; 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson initNodeTest(whatToShow); 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Initialize the context values for this expression 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * after it is cloned. 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param context The XPath runtime context for this 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * transformation. 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setRoot(int context, Object environment) 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.setRoot(context, environment); 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_axis > -1) 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_iterator = m_cdtm.getAxisIterator(m_axis); 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_iterator.setStartNode(m_context); 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Detaches the iterator from the set which it iterated over, releasing 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * any computational resources and placing the iterator in the INVALID 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * state. After<code>detach</code> has been invoked, calls to 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>nextNode</code> or<code>previousNode</code> will raise the 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * exception INVALID_STATE_ERR. 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void detach() 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_allowDetach) 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_axis > -1) 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_iterator = null; 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Always call the superclass detach last! 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.detach(); 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the next node via getFirstAttribute && getNextAttribute. 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected int getNextNode() 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_lastFetched = m_iterator.next(); 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get a cloned iterator. 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A new iterator that can be used without mutating this one. 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws CloneNotSupportedException 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Object clone() throws CloneNotSupportedException 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Do not access the location path itterator during this operation! 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson OneStepIterator clone = (OneStepIterator) super.clone(); 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_iterator != null) 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_iterator = m_iterator.cloneIterator(); 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return clone; 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get a cloned Iterator that is reset to the beginning 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * of the query. 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A cloned NodeIterator set of the start of the query. 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws CloneNotSupportedException 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public DTMIterator cloneWithReset() throws CloneNotSupportedException 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson OneStepIterator clone = (OneStepIterator) super.cloneWithReset(); 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_iterator = m_iterator; 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return clone; 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Tells if this is a reverse axes. Overrides AxesWalker#isReverseAxes. 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return true for this class. 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean isReverseAxes() 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_iterator.isReverse(); 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the current sub-context position. In order to do the 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * reverse axes count, for the moment this re-searches the axes 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * up to the predicate. An optimization on this is to cache 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * the nodes searched, but, for the moment, this case is probably 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * rare enough that the added complexity isn't worth it. 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param predicateIndex The predicate index of the proximity position. 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The pridicate index, or -1. 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected int getProximityPosition(int predicateIndex) 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(!isReverseAxes()) 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return super.getProximityPosition(predicateIndex); 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // A negative predicate index seems to occur with 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // (preceding-sibling::*|following-sibling::*)/ancestor::*[position()]/*[position()] 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // -sb 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(predicateIndex < 0) 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return -1; 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (m_proximityPositions[predicateIndex] <= 0) 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathContext xctxt = getXPathContext(); 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson OneStepIterator clone = (OneStepIterator) this.clone(); 2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int root = getRoot(); 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushCurrentNode(root); 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.setRoot(root, xctxt); 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // clone.setPredicateCount(predicateIndex); 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_predCount = predicateIndex; 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Count 'em all 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int count = 1; 2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int next; 2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson while (DTM.NULL != (next = clone.nextNode())) 2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson count++; 2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_proximityPositions[predicateIndex] += count; 2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch (CloneNotSupportedException cnse) 2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // can't happen 2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popCurrentNode(); 2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_proximityPositions[predicateIndex]; 2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * The number of nodes in the list. The range of valid child node indices 2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * is 0 to <code>length-1</code> inclusive. 2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The number of nodes in the list, always greater or equal to zero. 2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getLength() 2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(!isReverseAxes()) 2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return super.getLength(); 2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Tell if this is being called from within a predicate. 2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson boolean isPredicateTest = (this == m_execContext.getSubContextList()); 2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // And get how many total predicates are part of this step. 2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int predCount = getPredicateCount(); 2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // If we have already calculated the length, and the current predicate 2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // is the first predicate, then return the length. We don't cache 2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // the anything but the length of the list to the first predicate. 2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (-1 != m_length && isPredicateTest && m_predicateIndex < 1) 2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_length; 2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int count = 0; 2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathContext xctxt = getXPathContext(); 2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson OneStepIterator clone = (OneStepIterator) this.cloneWithReset(); 2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int root = getRoot(); 2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushCurrentNode(root); 2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.setRoot(root, xctxt); 2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_predCount = m_predicateIndex; 2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int next; 2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson while (DTM.NULL != (next = clone.nextNode())) 2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson count++; 2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch (CloneNotSupportedException cnse) 2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // can't happen 2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popCurrentNode(); 2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (isPredicateTest && m_predicateIndex < 1) 2904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_length = count; 2914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return count; 2934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Count backwards one proximity position. 2974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param i The predicate index. 2994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected void countProximityPosition(int i) 3014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(!isReverseAxes()) 3034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.countProximityPosition(i); 3044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else if (i < m_proximityPositions.length) 3054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_proximityPositions[i]--; 3064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Reset the iterator. 3104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void reset() 3124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.reset(); 3154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(null != m_iterator) 3164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_iterator.reset(); 3174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Returns the axis being iterated, if it is known. 3214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 3234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * types. 3244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getAxis() 3264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_axis; 3284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see Expression#deepEquals(Expression) 3324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean deepEquals(Expression expr) 3344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(!super.deepEquals(expr)) 3364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_axis != ((OneStepIterator)expr).m_axis) 3394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 3424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 346