1 16 19 package org.apache.xpath.axes; 20 21 import org.apache.xml.dtm.Axis; 22 import org.apache.xml.dtm.DTM; 23 import org.apache.xml.dtm.DTMAxisTraverser; 24 import org.apache.xml.dtm.DTMFilter; 25 import org.apache.xml.dtm.DTMIterator; 26 import org.apache.xpath.Expression; 27 import org.apache.xpath.XPathContext; 28 import org.apache.xpath.compiler.Compiler; 29 import org.apache.xpath.compiler.OpCodes; 30 import org.apache.xpath.patterns.NodeTest; 31 32 38 public class DescendantIterator extends LocPathIterator 39 { 40 49 DescendantIterator(Compiler compiler, int opPos, int analysis) 50 throws javax.xml.transform.TransformerException 51 { 52 53 super(compiler, opPos, analysis, false); 54 55 int firstStepPos = compiler.getFirstChildPos(opPos); 56 int stepType = compiler.getOp(firstStepPos); 57 58 boolean orSelf = (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType); 59 boolean fromRoot = false; 60 if (OpCodes.FROM_SELF == stepType) 61 { 62 orSelf = true; 63 } 65 else if(OpCodes.FROM_ROOT == stepType) 66 { 67 fromRoot = true; 68 int nextStepPos = compiler.getNextStepPos(firstStepPos); 70 if(compiler.getOp(nextStepPos) == OpCodes.FROM_DESCENDANTS_OR_SELF) 71 orSelf = true; 72 } 74 75 int nextStepPos = firstStepPos; 77 while(true) 78 { 79 nextStepPos = compiler.getNextStepPos(nextStepPos); 80 if(nextStepPos > 0) 81 { 82 int stepOp = compiler.getOp(nextStepPos); 83 if(OpCodes.ENDOP != stepOp) 84 firstStepPos = nextStepPos; 85 else 86 break; 87 } 88 else 89 break; 90 91 } 92 93 if((analysis & WalkerFactory.BIT_CHILD) != 0) 95 orSelf = false; 96 97 if(fromRoot) 98 { 99 if(orSelf) 100 m_axis = Axis.DESCENDANTSORSELFFROMROOT; 101 else 102 m_axis = Axis.DESCENDANTSFROMROOT; 103 } 104 else if(orSelf) 105 m_axis = Axis.DESCENDANTORSELF; 106 else 107 m_axis = Axis.DESCENDANT; 108 109 int whatToShow = compiler.getWhatToShow(firstStepPos); 110 111 if ((0 == (whatToShow 112 & (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_ELEMENT 113 | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) || 114 (whatToShow == DTMFilter.SHOW_ALL)) 115 initNodeTest(whatToShow); 116 else 117 { 118 initNodeTest(whatToShow, compiler.getStepNS(firstStepPos), 119 compiler.getStepLocalName(firstStepPos)); 120 } 121 initPredicateInfo(compiler, firstStepPos); 122 } 123 124 133 public DescendantIterator() 134 { 135 super(null); 136 m_axis = Axis.DESCENDANTSORSELFFROMROOT; 137 int whatToShow = DTMFilter.SHOW_ALL; 138 initNodeTest(whatToShow); 139 } 140 141 142 150 public DTMIterator cloneWithReset() throws CloneNotSupportedException 151 { 152 153 DescendantIterator clone = (DescendantIterator) super.cloneWithReset(); 154 clone.m_traverser = m_traverser; 155 156 clone.resetProximityPositions(); 157 158 return clone; 159 } 160 161 173 public int nextNode() 174 { 175 if(m_foundLast) 176 return DTM.NULL; 177 178 if(DTM.NULL == m_lastFetched) 179 { 180 resetProximityPositions(); 181 } 182 183 int next; 184 185 org.apache.xpath.VariableStack vars; 186 int savedStart; 187 if (-1 != m_stackFrame) 188 { 189 vars = m_execContext.getVarStack(); 190 191 savedStart = vars.getStackFrame(); 193 194 vars.setStackFrame(m_stackFrame); 195 } 196 else 197 { 198 vars = null; 200 savedStart = 0; 201 } 202 203 try 204 { 205 do 206 { 207 if(0 == m_extendedTypeID) 208 { 209 next = m_lastFetched = (DTM.NULL == m_lastFetched) 210 ? m_traverser.first(m_context) 211 : m_traverser.next(m_context, m_lastFetched); 212 } 213 else 214 { 215 next = m_lastFetched = (DTM.NULL == m_lastFetched) 216 ? m_traverser.first(m_context, m_extendedTypeID) 217 : m_traverser.next(m_context, m_lastFetched, 218 m_extendedTypeID); 219 } 220 221 if (DTM.NULL != next) 222 { 223 if(DTMIterator.FILTER_ACCEPT == acceptNode(next)) 224 break; 225 else 226 continue; 227 } 228 else 229 break; 230 } 231 while (next != DTM.NULL); 232 233 if (DTM.NULL != next) 234 { 235 m_pos++; 236 return next; 237 } 238 else 239 { 240 m_foundLast = true; 241 242 return DTM.NULL; 243 } 244 } 245 finally 246 { 247 if (-1 != m_stackFrame) 248 { 249 vars.setStackFrame(savedStart); 251 } 252 } 253 } 254 255 262 public void setRoot(int context, Object environment) 263 { 264 super.setRoot(context, environment); 265 m_traverser = m_cdtm.getAxisTraverser(m_axis); 266 267 String localName = getLocalName(); 268 String namespace = getNamespace(); 269 int what = m_whatToShow; 270 if(DTMFilter.SHOW_ALL == what 273 || localName == NodeTest.WILD 274 || namespace == NodeTest.WILD) 275 { 276 m_extendedTypeID = 0; 277 } 278 else 279 { 280 int type = getNodeTypeTest(what); 281 m_extendedTypeID = m_cdtm.getExpandedTypeID(namespace, localName, type); 282 } 283 284 } 285 286 294 public int asNode(XPathContext xctxt) 295 throws javax.xml.transform.TransformerException 296 { 297 if(getPredicateCount() > 0) 298 return super.asNode(xctxt); 299 300 int current = xctxt.getCurrentNode(); 301 302 DTM dtm = xctxt.getDTM(current); 303 DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis); 304 305 String localName = getLocalName(); 306 String namespace = getNamespace(); 307 int what = m_whatToShow; 308 309 311 if(DTMFilter.SHOW_ALL == what 314 || localName == NodeTest.WILD 315 || namespace == NodeTest.WILD) 316 { 317 return traverser.first(current); 318 } 319 else 320 { 321 int type = getNodeTypeTest(what); 322 int extendedType = dtm.getExpandedTypeID(namespace, localName, type); 323 return traverser.first(current, extendedType); 324 } 325 } 326 327 334 public void detach() 335 { 336 if (m_allowDetach) { 337 m_traverser = null; 338 m_extendedTypeID = 0; 339 340 super.detach(); 342 } 343 } 344 345 351 public int getAxis() 352 { 353 return m_axis; 354 } 355 356 357 358 transient protected DTMAxisTraverser m_traverser; 359 360 361 protected int m_axis; 362 363 364 protected int m_extendedTypeID; 365 366 369 public boolean deepEquals(Expression expr) 370 { 371 if(!super.deepEquals(expr)) 372 return false; 373 374 if(m_axis != ((DescendantIterator)expr).m_axis) 375 return false; 376 377 return true; 378 } 379 380 381 } 382 | Popular Tags |