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: FilterExprIterator.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.xpath.Expression; 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.ExpressionOwner; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathVisitor; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XNodeSet; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class FilterExprIterator extends BasicTestIterator 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = 2552176105165737614L; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The contained expression. Should be non-null. 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial */ 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private Expression m_expr; 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The result of executing m_expr. Needs to be deep cloned on clone op. */ 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private XNodeSet m_exprObj; 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean m_mustHardReset = false; 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean m_canDetachNodeset = true; 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Create a FilterExprIterator object. 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public FilterExprIterator() 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super(null); 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Create a FilterExprIterator object. 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public FilterExprIterator(Expression expr) 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super(null); 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = expr; 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Initialize the context values for this expression 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * after it is cloned. 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param context The XPath runtime context for this 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * transformation. 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setRoot(int context, Object environment) 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.setRoot(context, environment); 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context, 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_execContext, getPrefixResolver(), 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson getIsTopLevel(), m_stackFrame, m_expr); 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the next node via getNextXXX. Bottlenecked for derived class override. 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The next node on the axis, or DTM.NULL. 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson protected int getNextNode() 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_exprObj) 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_lastFetched = m_exprObj.nextNode(); 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_lastFetched = DTM.NULL; 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_lastFetched; 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Detaches the walker from the set which it iterated over, releasing 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * any computational resources and placing the iterator in the INVALID 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * state. 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void detach() 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.detach(); 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_exprObj.detach(); 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_exprObj = null; 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This function is used to fixup variables from QNames to stack frame 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * indexes at stylesheet build time. 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param vars List of QNames that correspond to variables. This list 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * should be searched backwards for the first qualified name that 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * corresponds to the variable reference qname. The position of the 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * QName in the vector from the start of the vector will be its position 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * in the stack frame (but variables above the globalsTop value will need 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to be offset to the current stack frame). 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void fixupVariables(java.util.Vector vars, int globalsSize) 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.fixupVariables(vars, globalsSize); 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr.fixupVariables(vars, globalsSize); 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the inner contained expression of this filter. 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Expression getInnerExpression() 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_expr; 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set the inner contained expression of this filter. 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setInnerExpression(Expression expr) 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson expr.exprSetParent(this); 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = expr; 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the analysis bits for this walker, as defined in the WalkerFactory. 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return One of WalkerFactory#BIT_DESCENDANT, etc. 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getAnalysisBits() 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != m_expr && m_expr instanceof PathComponent) 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return ((PathComponent) m_expr).getAnalysisBits(); 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return WalkerFactory.BIT_FILTER; 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Returns true if all the nodes in the iteration well be returned in document 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * order. 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Warning: This can only be called after setRoot has been called! 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return true as a default. 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean isDocOrdered() 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_exprObj.isDocOrdered(); 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson class filterExprOwner implements ExpressionOwner 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see ExpressionOwner#getExpression() 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Expression getExpression() 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_expr; 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see ExpressionOwner#setExpression(Expression) 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setExpression(Expression exp) 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson exp.exprSetParent(FilterExprIterator.this); 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr = exp; 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This will traverse the heararchy, calling the visitor for 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * each member. If the called visitor method returns 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * false, the subtree should not be called. 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param visitor The visitor whose appropriate method will be called. 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void callPredicateVisitors(XPathVisitor visitor) 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_expr.callVisitors(new filterExprOwner(), visitor); 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.callPredicateVisitors(visitor); 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see Expression#deepEquals(Expression) 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public boolean deepEquals(Expression expr) 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!super.deepEquals(expr)) 2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson FilterExprIterator fet = (FilterExprIterator) expr; 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!m_expr.deepEquals(fet.m_expr)) 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 215