1 16 19 package org.apache.xpath.axes; 20 21 import java.util.Vector ; 22 23 import org.apache.xalan.res.XSLMessages; 24 import org.apache.xml.dtm.DTM; 25 import org.apache.xml.dtm.DTMAxisTraverser; 26 import org.apache.xml.dtm.DTMIterator; 27 import org.apache.xpath.Expression; 28 import org.apache.xpath.ExpressionOwner; 29 import org.apache.xpath.XPathContext; 30 import org.apache.xpath.XPathVisitor; 31 import org.apache.xpath.compiler.Compiler; 32 import org.apache.xpath.res.XPATHErrorResources; 33 34 38 public class AxesWalker extends PredicatedNodeTest 39 implements Cloneable , PathComponent, ExpressionOwner 40 { 41 42 47 public AxesWalker(LocPathIterator locPathIterator, int axis) 48 { 49 super( locPathIterator ); 50 m_axis = axis; 51 } 52 53 public final WalkingIterator wi() 54 { 55 return (WalkingIterator)m_lpi; 56 } 57 58 68 public void init(Compiler compiler, int opPos, int stepType) 69 throws javax.xml.transform.TransformerException 70 { 71 72 initPredicateInfo(compiler, opPos); 73 74 } 76 77 84 public Object clone() throws CloneNotSupportedException 85 { 86 88 AxesWalker clone = (AxesWalker) super.clone(); 89 90 92 94 return clone; 95 } 96 97 110 AxesWalker cloneDeep(WalkingIterator cloneOwner, Vector cloneList) 111 throws CloneNotSupportedException 112 { 113 AxesWalker clone = findClone(this, cloneList); 114 if(null != clone) 115 return clone; 116 clone = (AxesWalker)this.clone(); 117 clone.setLocPathIterator(cloneOwner); 118 if(null != cloneList) 119 { 120 cloneList.addElement(this); 121 cloneList.addElement(clone); 122 } 123 124 if(wi().m_lastUsedWalker == this) 125 cloneOwner.m_lastUsedWalker = clone; 126 127 if(null != m_nextWalker) 128 clone.m_nextWalker = m_nextWalker.cloneDeep(cloneOwner, cloneList); 129 130 if(null != cloneList) 133 { 134 if(null != m_prevWalker) 135 clone.m_prevWalker = m_prevWalker.cloneDeep(cloneOwner, cloneList); 136 } 137 else 138 { 139 if(null != m_nextWalker) 140 clone.m_nextWalker.m_prevWalker = clone; 141 } 142 return clone; 143 } 144 145 154 static AxesWalker findClone(AxesWalker key, Vector cloneList) 155 { 156 if(null != cloneList) 157 { 158 int n = cloneList.size(); 160 for (int i = 0; i < n; i+=2) 161 { 162 if(key == cloneList.elementAt(i)) 163 return (AxesWalker)cloneList.elementAt(i+1); 164 } 165 } 166 return null; 167 } 168 169 174 public void detach() 175 { 176 m_currentNode = DTM.NULL; 177 m_dtm = null; 178 m_traverser = null; 179 m_isFresh = true; 180 m_root = DTM.NULL; 181 } 182 183 185 191 public int getRoot() 192 { 193 return m_root; 194 } 195 196 200 public int getAnalysisBits() 201 { 202 int axis = getAxis(); 203 int bit = WalkerFactory.getAnalysisBitFromAxes(axis); 204 return bit; 205 } 206 207 213 public void setRoot(int root) 214 { 215 XPathContext xctxt = wi().getXPathContext(); 217 m_dtm = xctxt.getDTM(root); 218 m_traverser = m_dtm.getAxisTraverser(m_axis); 219 m_isFresh = true; 220 m_foundLast = false; 221 m_root = root; 222 m_currentNode = root; 223 224 if (DTM.NULL == root) 225 { 226 throw new RuntimeException ( 227 XSLMessages.createXPATHMessage(XPATHErrorResources.ER_SETTING_WALKER_ROOT_TO_NULL, null)); } 229 230 resetProximityPositions(); 231 } 232 233 247 public final int getCurrentNode() 248 { 249 return m_currentNode; 250 } 251 252 258 public void setNextWalker(AxesWalker walker) 259 { 260 m_nextWalker = walker; 261 } 262 263 269 public AxesWalker getNextWalker() 270 { 271 return m_nextWalker; 272 } 273 274 281 public void setPrevWalker(AxesWalker walker) 282 { 283 m_prevWalker = walker; 284 } 285 286 293 public AxesWalker getPrevWalker() 294 { 295 return m_prevWalker; 296 } 297 298 306 private int returnNextNode(int n) 307 { 308 309 return n; 310 } 311 312 317 protected int getNextNode() 318 { 319 if (m_foundLast) 320 return DTM.NULL; 321 322 if (m_isFresh) 323 { 324 m_currentNode = m_traverser.first(m_root); 325 m_isFresh = false; 326 } 327 else if(DTM.NULL != m_currentNode) 331 { 332 m_currentNode = m_traverser.next(m_root, m_currentNode); 333 } 334 335 if (DTM.NULL == m_currentNode) 336 this.m_foundLast = true; 337 338 return m_currentNode; 339 } 340 341 350 public int nextNode() 351 { 352 int nextNode = DTM.NULL; 353 AxesWalker walker = wi().getLastUsedWalker(); 354 355 while (true) 356 { 357 if (null == walker) 358 break; 359 360 nextNode = walker.getNextNode(); 361 362 if (DTM.NULL == nextNode) 363 { 364 365 walker = walker.m_prevWalker; 366 } 367 else 368 { 369 if (walker.acceptNode(nextNode) != DTMIterator.FILTER_ACCEPT) 370 { 371 continue; 372 } 373 374 if (null == walker.m_nextWalker) 375 { 376 wi().setLastUsedWalker(walker); 377 378 break; 380 } 381 else 382 { 383 AxesWalker prev = walker; 384 385 walker = walker.m_nextWalker; 386 387 walker.setRoot(nextNode); 388 389 walker.m_prevWalker = prev; 390 391 continue; 392 } 393 } } 396 return nextNode; 397 } 398 399 401 409 public int getLastPos(XPathContext xctxt) 410 { 411 412 int pos = getProximityPosition(); 413 414 AxesWalker walker; 415 416 try 417 { 418 walker = (AxesWalker) clone(); 419 } 420 catch (CloneNotSupportedException cnse) 421 { 422 return -1; 423 } 424 425 walker.setPredicateCount(walker.getPredicateCount() - 1); 426 walker.setNextWalker(null); 427 walker.setPrevWalker(null); 428 429 WalkingIterator lpi = wi(); 430 AxesWalker savedWalker = lpi.getLastUsedWalker(); 431 432 try 433 { 434 lpi.setLastUsedWalker(walker); 435 436 int next; 437 438 while (DTM.NULL != (next = walker.nextNode())) 439 { 440 pos++; 441 } 442 443 } 445 finally 446 { 447 lpi.setLastUsedWalker(savedWalker); 448 } 449 450 return pos; 452 } 453 454 456 462 private DTM m_dtm; 463 464 469 public void setDefaultDTM(DTM dtm) 470 { 471 m_dtm = dtm; 472 } 473 474 479 public DTM getDTM(int node) 480 { 481 return wi().getXPathContext().getDTM(node); 483 } 484 485 492 public boolean isDocOrdered() 493 { 494 return true; 495 } 496 497 503 public int getAxis() 504 { 505 return m_axis; 506 } 507 508 517 public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) 518 { 519 if(visitor.visitStep(owner, this)) 520 { 521 callPredicateVisitors(visitor); 522 if(null != m_nextWalker) 523 { 524 m_nextWalker.callVisitors(this, visitor); 525 } 526 } 527 } 528 529 532 public Expression getExpression() 533 { 534 return m_nextWalker; 535 } 536 537 540 public void setExpression(Expression exp) 541 { 542 exp.exprSetParent(this); 543 m_nextWalker = (AxesWalker)exp; 544 } 545 546 549 public boolean deepEquals(Expression expr) 550 { 551 if (!super.deepEquals(expr)) 552 return false; 553 554 AxesWalker walker = (AxesWalker)expr; 555 if(this.m_axis != walker.m_axis) 556 return false; 557 558 return true; 559 } 560 561 564 transient int m_root = DTM.NULL; 565 566 569 private transient int m_currentNode = DTM.NULL; 570 571 572 transient boolean m_isFresh; 573 574 576 protected AxesWalker m_nextWalker; 577 578 580 AxesWalker m_prevWalker; 581 582 583 protected int m_axis = -1; 584 585 586 protected DTMAxisTraverser m_traverser; 587 } 588 | Popular Tags |