1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18/* 19 * $Id: FilterExprIterator.java 468655 2006-10-28 07:12:06Z minchau $ 20 */ 21package org.apache.xpath.axes; 22 23import org.apache.xml.dtm.DTM; 24import org.apache.xpath.Expression; 25import org.apache.xpath.ExpressionOwner; 26import org.apache.xpath.XPathVisitor; 27import org.apache.xpath.objects.XNodeSet; 28 29public class FilterExprIterator extends BasicTestIterator 30{ 31 static final long serialVersionUID = 2552176105165737614L; 32 /** The contained expression. Should be non-null. 33 * @serial */ 34 private Expression m_expr; 35 36 /** The result of executing m_expr. Needs to be deep cloned on clone op. */ 37 transient private XNodeSet m_exprObj; 38 39 private boolean m_mustHardReset = false; 40 private boolean m_canDetachNodeset = true; 41 42 /** 43 * Create a FilterExprIterator object. 44 * 45 */ 46 public FilterExprIterator() 47 { 48 super(null); 49 } 50 51 /** 52 * Create a FilterExprIterator object. 53 * 54 */ 55 public FilterExprIterator(Expression expr) 56 { 57 super(null); 58 m_expr = expr; 59 } 60 61 /** 62 * Initialize the context values for this expression 63 * after it is cloned. 64 * 65 * @param context The XPath runtime context for this 66 * transformation. 67 */ 68 public void setRoot(int context, Object environment) 69 { 70 super.setRoot(context, environment); 71 72 m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context, 73 m_execContext, getPrefixResolver(), 74 getIsTopLevel(), m_stackFrame, m_expr); 75 } 76 77 78 /** 79 * Get the next node via getNextXXX. Bottlenecked for derived class override. 80 * @return The next node on the axis, or DTM.NULL. 81 */ 82 protected int getNextNode() 83 { 84 if (null != m_exprObj) 85 { 86 m_lastFetched = m_exprObj.nextNode(); 87 } 88 else 89 m_lastFetched = DTM.NULL; 90 91 return m_lastFetched; 92 } 93 94 /** 95 * Detaches the walker from the set which it iterated over, releasing 96 * any computational resources and placing the iterator in the INVALID 97 * state. 98 */ 99 public void detach() 100 { 101 super.detach(); 102 m_exprObj.detach(); 103 m_exprObj = null; 104 } 105 106 /** 107 * This function is used to fixup variables from QNames to stack frame 108 * indexes at stylesheet build time. 109 * @param vars List of QNames that correspond to variables. This list 110 * should be searched backwards for the first qualified name that 111 * corresponds to the variable reference qname. The position of the 112 * QName in the vector from the start of the vector will be its position 113 * in the stack frame (but variables above the globalsTop value will need 114 * to be offset to the current stack frame). 115 */ 116 public void fixupVariables(java.util.Vector vars, int globalsSize) 117 { 118 super.fixupVariables(vars, globalsSize); 119 m_expr.fixupVariables(vars, globalsSize); 120 } 121 122 /** 123 * Get the inner contained expression of this filter. 124 */ 125 public Expression getInnerExpression() 126 { 127 return m_expr; 128 } 129 130 /** 131 * Set the inner contained expression of this filter. 132 */ 133 public void setInnerExpression(Expression expr) 134 { 135 expr.exprSetParent(this); 136 m_expr = expr; 137 } 138 139 /** 140 * Get the analysis bits for this walker, as defined in the WalkerFactory. 141 * @return One of WalkerFactory#BIT_DESCENDANT, etc. 142 */ 143 public int getAnalysisBits() 144 { 145 if (null != m_expr && m_expr instanceof PathComponent) 146 { 147 return ((PathComponent) m_expr).getAnalysisBits(); 148 } 149 return WalkerFactory.BIT_FILTER; 150 } 151 152 /** 153 * Returns true if all the nodes in the iteration well be returned in document 154 * order. 155 * Warning: This can only be called after setRoot has been called! 156 * 157 * @return true as a default. 158 */ 159 public boolean isDocOrdered() 160 { 161 return m_exprObj.isDocOrdered(); 162 } 163 164 class filterExprOwner implements ExpressionOwner 165 { 166 /** 167 * @see ExpressionOwner#getExpression() 168 */ 169 public Expression getExpression() 170 { 171 return m_expr; 172 } 173 174 /** 175 * @see ExpressionOwner#setExpression(Expression) 176 */ 177 public void setExpression(Expression exp) 178 { 179 exp.exprSetParent(FilterExprIterator.this); 180 m_expr = exp; 181 } 182 183 } 184 185 /** 186 * This will traverse the heararchy, calling the visitor for 187 * each member. If the called visitor method returns 188 * false, the subtree should not be called. 189 * 190 * @param visitor The visitor whose appropriate method will be called. 191 */ 192 public void callPredicateVisitors(XPathVisitor visitor) 193 { 194 m_expr.callVisitors(new filterExprOwner(), visitor); 195 196 super.callPredicateVisitors(visitor); 197 } 198 199 /** 200 * @see Expression#deepEquals(Expression) 201 */ 202 public boolean deepEquals(Expression expr) 203 { 204 if (!super.deepEquals(expr)) 205 return false; 206 207 FilterExprIterator fet = (FilterExprIterator) expr; 208 if (!m_expr.deepEquals(fet.m_expr)) 209 return false; 210 211 return true; 212 } 213 214} 215