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: PredicatedNodeTest.java 468655 2006-10-28 07:12:06Z minchau $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xpath.axes; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTM; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMIterator; 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.PrefixResolver; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.Expression; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.ExpressionOwner; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathContext; 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathVisitor; 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.compiler.Compiler; 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.patterns.NodeTest; 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic abstract class PredicatedNodeTest extends NodeTest implements SubContextList 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = -6193530757296377351L; 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Construct an AxesWalker using a LocPathIterator. 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param locPathIterator non-null reference to the parent iterator. 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PredicatedNodeTest(LocPathIterator locPathIterator) 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_lpi = locPathIterator; 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Construct an AxesWalker. The location path iterator will have to be set 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * before use. 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PredicatedNodeTest() 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Read the object from a serialization stream. 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param stream Input stream to read from 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws java.io.IOException 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private void readObject(java.io.ObjectInputStream stream) 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws java.io.IOException, javax.xml.transform.TransformerException 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson stream.defaultReadObject(); 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicateIndex = -1; 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson resetProximityPositions(); 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch (ClassNotFoundException cnfe) 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new javax.xml.transform.TransformerException(cnfe); 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get a cloned PrdicatedNodeTest. 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A new PredicatedNodeTest that can be used without mutating this one. 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws CloneNotSupportedException 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Object clone() throws CloneNotSupportedException 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Do not access the location path itterator during this operation! 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PredicatedNodeTest clone = (PredicatedNodeTest) super.clone(); 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ((null != this.m_proximityPositions) 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson && (this.m_proximityPositions == clone.m_proximityPositions)) 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_proximityPositions = new int[this.m_proximityPositions.length]; 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.arraycopy(this.m_proximityPositions, 0, 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_proximityPositions, 0, 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.m_proximityPositions.length); 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(clone.m_lpi == this) 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_lpi = (LocPathIterator)clone; 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return clone; 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Only for clones for findLastPos. See bug4638. 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected int m_predCount = -1; 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the number of predicates that this walker has. 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return the number of predicates that this walker has. 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getPredicateCount() 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(-1 == m_predCount) 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return (null == m_predicates) ? 0 : m_predicates.length; 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_predCount; 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set the number of predicates that this walker has. This does more 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * that one would think, as it creates a new predicate array of the 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * size of the count argument, and copies count predicates into the new 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * one from the old, and then reassigns the predicates value. All this 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to keep from having to have a predicate count value. 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param count The number of predicates, which must be equal or less 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * than the existing count. 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setPredicateCount(int count) 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(count > 0) 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Expression[] newPredicates = new Expression[count]; 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < count; i++) 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson newPredicates[i] = m_predicates[i]; 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates = newPredicates; 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates = null; 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Init predicate info. 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param compiler The Compiler object that has information about this 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * walker in the op map. 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param opPos The op code position of this location step. 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected void initPredicateInfo(Compiler compiler, int opPos) 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int pos = compiler.getFirstPredicateOpPos(opPos); 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(pos > 0) 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates = compiler.getCompiledPredicates(pos); 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(null != m_predicates) 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for(int i = 0; i < m_predicates.length; i++) 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates[i].exprSetParent(this); 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get a predicate expression at the given index. 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param index Index of the predicate. 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A predicate expression. 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Expression getPredicate(int index) 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_predicates[index]; 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the current sub-context position. 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The node position of this walker in the sub-context node list. 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getProximityPosition() 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("getProximityPosition - m_predicateIndex: "+m_predicateIndex); 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return getProximityPosition(m_predicateIndex); 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the current sub-context position. 2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param xctxt The XPath runtime context. 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The node position of this walker in the sub-context node list. 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getProximityPosition(XPathContext xctxt) 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return getProximityPosition(); 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the index of the last node that can be itterated to. 2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param xctxt XPath runtime context. 2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return the index of the last node that can be itterated to. 2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public abstract int getLastPos(XPathContext xctxt); 2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the current sub-context position. 2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param predicateIndex The index of the predicate where the proximity 2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * should be taken from. 2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The node position of this walker in the sub-context node list. 2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected int getProximityPosition(int predicateIndex) 2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return (predicateIndex >= 0) ? m_proximityPositions[predicateIndex] : 0; 2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Reset the proximity positions counts. 2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void resetProximityPositions() 2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int nPredicates = getPredicateCount(); 2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (nPredicates > 0) 2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null == m_proximityPositions) 2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_proximityPositions = new int[nPredicates]; 2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < nPredicates; i++) 2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson initProximityPosition(i); 2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch(Exception e) 2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // TODO: Fix this... 2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new org.apache.xml.utils.WrappedRuntimeException(e); 2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Init the proximity position to zero for a forward axes. 2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param i The index into the m_proximityPositions array. 2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void initProximityPosition(int i) throws javax.xml.transform.TransformerException 2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_proximityPositions[i] = 0; 2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Count forward one proximity position. 2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param i The index into the m_proximityPositions array, where the increment 2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * will occur. 2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected void countProximityPosition(int i) 2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Note that in the case of a UnionChildIterator, this may be a 2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // static object and so m_proximityPositions may indeed be null! 2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int[] pp = m_proximityPositions; 2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ((null != pp) && (i < pp.length)) 2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson pp[i]++; 2894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Tells if this is a reverse axes. 2934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return false, unless a derived class overrides. 2954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean isReverseAxes() 2974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 2994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get which predicate is executing. 3034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The current predicate index, or -1 if no predicate is executing. 3054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getPredicateIndex() 3074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_predicateIndex; 3094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Process the predicates. 3134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param context The current context node. 3154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param xctxt The XPath runtime context. 3164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return the result of executing the predicate expressions. 3184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 3204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson boolean executePredicates(int context, XPathContext xctxt) 3224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException 3234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int nPredicates = getPredicateCount(); 3264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("nPredicates: "+nPredicates); 3274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (nPredicates == 0) 3284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 3294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PrefixResolver savedResolver = xctxt.getNamespaceContext(); 3314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 3334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicateIndex = 0; 3354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushSubContextList(this); 3364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushNamespaceContext(m_lpi.getPrefixResolver()); 3374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushCurrentNode(context); 3384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < nPredicates; i++) 3404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("Executing predicate expression - waiting count: "+m_lpi.getWaitingCount()); 3424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject pred = m_predicates[i].execute(xctxt); 3434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("\nBack from executing predicate expression - waiting count: "+m_lpi.getWaitingCount()); 3444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("pred.getType(): "+pred.getType()); 3454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (XObject.CLASS_NUMBER == pred.getType()) 3464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (DEBUG_PREDICATECOUNTING) 3484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.flush(); 3504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("\n===== start predicate count ========"); 3514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("m_predicateIndex: " + m_predicateIndex); 3524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("getProximityPosition(m_predicateIndex): " 3534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // + getProximityPosition(m_predicateIndex)); 3544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("pred.num(): " + pred.num()); 3554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int proxPos = this.getProximityPosition(m_predicateIndex); 3584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int predIndex = (int) pred.num(); 3594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (proxPos != predIndex) 3604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (DEBUG_PREDICATECOUNTING) 3624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("\nnode context: "+nodeToString(context)); 3644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("index predicate is false: "+proxPos); 3654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("\n===== end predicate count ========"); 3664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else if (DEBUG_PREDICATECOUNTING) 3704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("\nnode context: "+nodeToString(context)); 3724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("index predicate is true: "+proxPos); 3734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson System.out.println("\n===== end predicate count ========"); 3744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // If there is a proximity index that will not change during the 3774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // course of itteration, then we know there can be no more true 3784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // occurances of this predicate, so flag that we're done after 3794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // this. 3804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // 3814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // bugzilla 14365 3824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // We can't set m_foundLast = true unless we're sure that -all- 3834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // remaining parameters are stable, or else last() fails. Fixed so 3844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // only sets m_foundLast if on the last predicate 3854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_predicates[i].isStableNumber() && i == nPredicates - 1) 3864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_foundLast = true; 3884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else if (!pred.bool()) 3914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson countProximityPosition(++m_predicateIndex); 3944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 3974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popCurrentNode(); 3994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popNamespaceContext(); 4004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popSubContextList(); 4014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicateIndex = -1; 4024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 4054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 4084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This function is used to fixup variables from QNames to stack frame 4094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * indexes at stylesheet build time. 4104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param vars List of QNames that correspond to variables. This list 4114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * should be searched backwards for the first qualified name that 4124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * corresponds to the variable reference qname. The position of the 4134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * QName in the vector from the start of the vector will be its position 4144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * in the stack frame (but variables above the globalsTop value will need 4154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to be offset to the current stack frame). 4164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 4174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void fixupVariables(java.util.Vector vars, int globalsSize) 4184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.fixupVariables(vars, globalsSize); 4204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int nPredicates = getPredicateCount(); 4224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < nPredicates; i++) 4244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates[i].fixupVariables(vars, globalsSize); 4264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 4314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Diagnostics. 4324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param n Node to give diagnostic information about, or null. 4344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Informative string about the argument. 4364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 4374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected String nodeToString(int n) 4384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(DTM.NULL != n) 4404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson DTM dtm = m_lpi.getXPathContext().getDTM(n); 4424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return dtm.getNodeName(n) + "{" + (n+1) + "}"; 4434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 4454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return "null"; 4474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson //=============== NodeFilter Implementation =============== 4514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 4534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Test whether a specified node is visible in the logical view of a 4544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * TreeWalker or NodeIterator. This function will be called by the 4554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * implementation of TreeWalker and NodeIterator; it is not intended to 4564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * be called directly from user code. 4574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param n The node to check to see if it passes the filter or not. 4584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return a constant to determine whether the node is accepted, 4594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * rejected, or skipped, as defined above . 4604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 4614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public short acceptNode(int n) 4624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathContext xctxt = m_lpi.getXPathContext(); 4654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 4674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushCurrentNode(n); 4694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject score = execute(xctxt, n); 4714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // System.out.println("\n::acceptNode - score: "+score.num()+"::"); 4734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (score != NodeTest.SCORE_NONE) 4744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (getPredicateCount() > 0) 4764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson countProximityPosition(0); 4784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!executePredicates(n, xctxt)) 4804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return DTMIterator.FILTER_SKIP; 4814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return DTMIterator.FILTER_ACCEPT; 4844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch (javax.xml.transform.TransformerException se) 4874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // TODO: Fix this. 4904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new RuntimeException(se.getMessage()); 4914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 4934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popCurrentNode(); 4954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return DTMIterator.FILTER_SKIP; 4984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 5024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the owning location path iterator. 5034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return the owning location path iterator, which should not be null. 5054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public LocPathIterator getLocPathIterator() 5074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_lpi; 5094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 5124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set the location path iterator owner for this walker. Besides 5134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * initialization, this function is called during cloning operations. 5144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param li non-null reference to the owning location path iterator. 5164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setLocPathIterator(LocPathIterator li) 5184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_lpi = li; 5204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(this != li) 5214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson li.exprSetParent(this); 5224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 5254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Tell if this expression or it's subexpressions can traverse outside 5264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * the current subtree. 5274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return true if traversal outside the context node's subtree can occur. 5294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean canTraverseOutsideSubtree() 5314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int n = getPredicateCount(); 5334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < n; i++) 5344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(getPredicate(i).canTraverseOutsideSubtree()) 5364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 5374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 5394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 5424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This will traverse the heararchy, calling the visitor for 5434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * each member. If the called visitor method returns 5444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * false, the subtree should not be called. 5454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param visitor The visitor whose appropriate method will be called. 5474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void callPredicateVisitors(XPathVisitor visitor) 5494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_predicates) 5514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int n = m_predicates.length; 5534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < n; i++) 5544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ExpressionOwner predOwner = new PredOwner(i); 5564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (visitor.visitPredicate(predOwner, m_predicates[i])) 5574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates[i].callVisitors(predOwner, visitor); 5594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 5664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see Expression#deepEquals(Expression) 5674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean deepEquals(Expression expr) 5694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!super.deepEquals(expr)) 5714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 5724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PredicatedNodeTest pnt = (PredicatedNodeTest) expr; 5744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_predicates) 5754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int n = m_predicates.length; 5784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ((null == pnt.m_predicates) || (pnt.m_predicates.length != n)) 5794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 5804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < n; i++) 5814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 5824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!m_predicates[i].deepEquals(pnt.m_predicates[i])) 5834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 5844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else if (null != pnt.m_predicates) 5874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 5884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 5904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** This is true if nextNode returns null. */ 5934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient protected boolean m_foundLast = false; 5944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The owning location path iterator. 5964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial */ 5974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected LocPathIterator m_lpi; 5984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 6004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Which predicate we are executing. 6014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 6024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient int m_predicateIndex = -1; 6034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The list of predicate expressions. Is static and does not need 6054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to be deep cloned. 6064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial 6074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 6084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private Expression[] m_predicates; 6094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 6114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * An array of counts that correspond to the number 6124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * of predicates the step contains. 6134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 6144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient protected int[] m_proximityPositions; 6154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** If true, diagnostic messages about predicate execution will be posted. */ 6174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final boolean DEBUG_PREDICATECOUNTING = false; 6184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson class PredOwner implements ExpressionOwner 6204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 6214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int m_index; 6224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PredOwner(int index) 6244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 6254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_index = index; 6264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 6274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 6294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see ExpressionOwner#getExpression() 6304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 6314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Expression getExpression() 6324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 6334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_predicates[m_index]; 6344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 6354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 6384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see ExpressionOwner#setExpression(Expression) 6394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 6404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setExpression(Expression exp) 6414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 6424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson exp.exprSetParent(PredicatedNodeTest.this); 6434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_predicates[m_index] = exp; 6444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 6454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 6464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 6474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 648