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