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