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: FilterExprWalker.java 469367 2006-10-31 04:41:08Z minchau $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xpath.axes; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.Axis; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTM; 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMIterator; 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.compiler.OpCodes; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XNodeSet; 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP, 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * op codes. 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see <a href="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a> 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class FilterExprWalker extends AxesWalker 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = 5457182471424488375L; 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Construct a FilterExprWalker using a LocPathIterator. 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param locPathIterator non-null reference to the parent iterator. 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public FilterExprWalker(WalkingIterator locPathIterator) 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super(locPathIterator, Axis.FILTEREDLIST); 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Init a FilterExprWalker. 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param compiler non-null reference to the Compiler that is constructing. 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param opPos positive opcode position for this step. 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param stepType The type of step. 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void init(Compiler compiler, int opPos, int stepType) 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.init(compiler, opPos, stepType); 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Smooth over an anomily in the opcode map... 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson switch (stepType) 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case OpCodes.OP_FUNCTION : 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case OpCodes.OP_EXTFUNCTION : 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_mustHardReset = true; 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case OpCodes.OP_GROUP : 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case OpCodes.OP_VARIABLE : 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = compiler.compile(opPos); 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr.exprSetParent(this); 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson //if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof org.apache.xalan.templates.FuncKey)) 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(m_expr instanceof org.apache.xpath.operations.Variable) 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // hack/temp workaround 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_canDetachNodeset = false; 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson break; 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson default : 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = compiler.compile(opPos + 2); 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr.exprSetParent(this); 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// if(m_expr instanceof WalkingIterator) 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// { 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// WalkingIterator wi = (WalkingIterator)m_expr; 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// if(wi.getFirstWalker() instanceof FilterExprWalker) 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// { 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// FilterExprWalker fw = (FilterExprWalker)wi.getFirstWalker(); 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// if(null == fw.getNextWalker()) 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// { 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// m_expr = fw.m_expr; 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// m_expr.exprSetParent(this); 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// } 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// } 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// } 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Detaches the walker from the set which it iterated over, releasing 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * any computational resources and placing the iterator in the INVALID 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * state. 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void detach() 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.detach(); 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (m_canDetachNodeset) 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_exprObj.detach(); 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_exprObj = null; 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set the root node of the TreeWalker. 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param root non-null reference to the root, or starting point of 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * the query. 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setRoot(int root) 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.setRoot(root); 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_exprObj = FilterExprIteratorSimple.executeFilterExpr(root, 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_lpi.getXPathContext(), m_lpi.getPrefixResolver(), 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_lpi.getIsTopLevel(), m_lpi.m_stackFrame, m_expr); 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get a cloned FilterExprWalker. 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A new FilterExprWalker that can be used without mutating this one. 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws CloneNotSupportedException 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Object clone() throws CloneNotSupportedException 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson FilterExprWalker clone = (FilterExprWalker) super.clone(); 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_exprObj) 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson clone.m_exprObj = (XNodeSet) m_exprObj.clone(); 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return clone; 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This method needs to override AxesWalker.acceptNode because FilterExprWalkers 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * don't need to, and shouldn't, do a node test. 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param n The node to check to see if it passes the filter or not. 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return a constant to determine whether the node is accepted, 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * rejected, or skipped, as defined above . 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public short acceptNode(int n) 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (getPredicateCount() > 0) 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson countProximityPosition(0); 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!executePredicates(n, m_lpi.getXPathContext())) 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return DTMIterator.FILTER_SKIP; 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return DTMIterator.FILTER_ACCEPT; 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch (javax.xml.transform.TransformerException se) 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new RuntimeException(se.getMessage()); 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Moves the <code>TreeWalker</code> to the next visible node in document 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * order relative to the current node, and returns the new node. If the 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * current node has no next node, or if the search for nextNode attempts 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to step upward from the TreeWalker's root node, returns 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>null</code> , and retains the current node. 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The new node, or <code>null</code> if the current node has no 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * next node in the TreeWalker's logical view. 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getNextNode() 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_exprObj) 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int next = m_exprObj.nextNode(); 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return next; 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return DTM.NULL; 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the index of the last node that can be itterated to. 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param xctxt XPath runtime context. 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return the index of the last node that can be itterated to. 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getLastPos(XPathContext xctxt) 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_exprObj.getLength(); 2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The contained expression. Should be non-null. 2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial */ 2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private Expression m_expr; 2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The result of executing m_expr. Needs to be deep cloned on clone op. */ 2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private XNodeSet m_exprObj; 2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean m_mustHardReset = false; 2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean m_canDetachNodeset = true; 2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This function is used to fixup variables from QNames to stack frame 2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * indexes at stylesheet build time. 2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param vars List of QNames that correspond to variables. This list 2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * should be searched backwards for the first qualified name that 2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * corresponds to the variable reference qname. The position of the 2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * QName in the vector from the start of the vector will be its position 2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * in the stack frame (but variables above the globalsTop value will need 2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to be offset to the current stack frame). 2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void fixupVariables(java.util.Vector vars, int globalsSize) 2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.fixupVariables(vars, globalsSize); 2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr.fixupVariables(vars, globalsSize); 2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the inner contained expression of this filter. 2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Expression getInnerExpression() 2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_expr; 2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set the inner contained expression of this filter. 2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setInnerExpression(Expression expr) 2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson expr.exprSetParent(this); 2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = expr; 2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the analysis bits for this walker, as defined in the WalkerFactory. 2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return One of WalkerFactory#BIT_DESCENDANT, etc. 2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getAnalysisBits() 2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_expr && m_expr instanceof PathComponent) 2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return ((PathComponent) m_expr).getAnalysisBits(); 2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return WalkerFactory.BIT_FILTER; 2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Returns true if all the nodes in the iteration well be returned in document 2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * order. 2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Warning: This can only be called after setRoot has been called! 2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return true as a default. 2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean isDocOrdered() 2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_exprObj.isDocOrdered(); 2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Returns the axis being iterated, if it is known. 2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 2904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * types. 2914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getAxis() 2934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_exprObj.getAxis(); 2954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson class filterExprOwner implements ExpressionOwner 2984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see ExpressionOwner#getExpression() 3014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Expression getExpression() 3034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_expr; 3054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see ExpressionOwner#setExpression(Expression) 3094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setExpression(Expression exp) 3114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson exp.exprSetParent(FilterExprWalker.this); 3134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = exp; 3144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This will traverse the heararchy, calling the visitor for 3194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * each member. If the called visitor method returns 3204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * false, the subtree should not be called. 3214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param visitor The visitor whose appropriate method will be called. 3234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void callPredicateVisitors(XPathVisitor visitor) 3254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr.callVisitors(new filterExprOwner(), visitor); 3274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.callPredicateVisitors(visitor); 3294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see Expression#deepEquals(Expression) 3344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean deepEquals(Expression expr) 3364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!super.deepEquals(expr)) 3384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson FilterExprWalker walker = (FilterExprWalker)expr; 3414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(!m_expr.deepEquals(walker.m_expr)) 3424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 3454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 350