001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: FilterExprIterator.java 468655 2006-10-28 07:12:06Z minchau $ 020 */ 021 package org.apache.xpath.axes; 022 023 import org.apache.xml.dtm.DTM; 024 import org.apache.xpath.Expression; 025 import org.apache.xpath.ExpressionOwner; 026 import org.apache.xpath.XPathVisitor; 027 import org.apache.xpath.objects.XNodeSet; 028 029 public class FilterExprIterator extends BasicTestIterator 030 { 031 static final long serialVersionUID = 2552176105165737614L; 032 /** The contained expression. Should be non-null. 033 * @serial */ 034 private Expression m_expr; 035 036 /** The result of executing m_expr. Needs to be deep cloned on clone op. */ 037 transient private XNodeSet m_exprObj; 038 039 private boolean m_mustHardReset = false; 040 private boolean m_canDetachNodeset = true; 041 042 /** 043 * Create a FilterExprIterator object. 044 * 045 */ 046 public FilterExprIterator() 047 { 048 super(null); 049 } 050 051 /** 052 * Create a FilterExprIterator object. 053 * 054 */ 055 public FilterExprIterator(Expression expr) 056 { 057 super(null); 058 m_expr = expr; 059 } 060 061 /** 062 * Initialize the context values for this expression 063 * after it is cloned. 064 * 065 * @param context The XPath runtime context for this 066 * transformation. 067 */ 068 public void setRoot(int context, Object environment) 069 { 070 super.setRoot(context, environment); 071 072 m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context, 073 m_execContext, getPrefixResolver(), 074 getIsTopLevel(), m_stackFrame, m_expr); 075 } 076 077 078 /** 079 * Get the next node via getNextXXX. Bottlenecked for derived class override. 080 * @return The next node on the axis, or DTM.NULL. 081 */ 082 protected int getNextNode() 083 { 084 if (null != m_exprObj) 085 { 086 m_lastFetched = m_exprObj.nextNode(); 087 } 088 else 089 m_lastFetched = DTM.NULL; 090 091 return m_lastFetched; 092 } 093 094 /** 095 * Detaches the walker from the set which it iterated over, releasing 096 * any computational resources and placing the iterator in the INVALID 097 * state. 098 */ 099 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 }