1 16 19 package org.apache.xpath.axes; 20 21 import org.apache.xml.dtm.DTM; 22 import org.apache.xml.dtm.DTMIterator; 23 import org.apache.xml.utils.PrefixResolver; 24 import org.apache.xpath.Expression; 25 import org.apache.xpath.ExpressionOwner; 26 import org.apache.xpath.XPathContext; 27 import org.apache.xpath.XPathVisitor; 28 import org.apache.xpath.compiler.Compiler; 29 import org.apache.xpath.objects.XObject; 30 import org.apache.xpath.patterns.NodeTest; 31 32 public abstract class PredicatedNodeTest extends NodeTest implements SubContextList 33 { 34 35 40 PredicatedNodeTest(LocPathIterator locPathIterator) 41 { 42 m_lpi = locPathIterator; 43 } 44 45 49 PredicatedNodeTest() 50 { 51 } 52 53 61 private void readObject(java.io.ObjectInputStream stream) 62 throws java.io.IOException , javax.xml.transform.TransformerException 63 { 64 try 65 { 66 stream.defaultReadObject(); 67 m_predicateIndex = -1; 68 resetProximityPositions(); 69 } 70 catch (ClassNotFoundException cnfe) 71 { 72 throw new javax.xml.transform.TransformerException (cnfe); 73 } 74 } 75 76 83 public Object clone() throws CloneNotSupportedException 84 { 85 87 PredicatedNodeTest clone = (PredicatedNodeTest) super.clone(); 88 89 if ((null != this.m_proximityPositions) 90 && (this.m_proximityPositions == clone.m_proximityPositions)) 91 { 92 clone.m_proximityPositions = new int[this.m_proximityPositions.length]; 93 94 System.arraycopy(this.m_proximityPositions, 0, 95 clone.m_proximityPositions, 0, 96 this.m_proximityPositions.length); 97 } 98 99 if(clone.m_lpi == this) 100 clone.m_lpi = (LocPathIterator)clone; 101 102 return clone; 103 } 104 105 protected int m_predCount = -1; 107 108 113 public int getPredicateCount() 114 { 115 if(-1 == m_predCount) 116 return (null == m_predicates) ? 0 : m_predicates.length; 117 else 118 return m_predCount; 119 } 120 121 131 public void setPredicateCount(int count) 132 { 133 if(count > 0) 134 { 135 Expression[] newPredicates = new Expression[count]; 136 for (int i = 0; i < count; i++) 137 { 138 newPredicates[i] = m_predicates[i]; 139 } 140 m_predicates = newPredicates; 141 } 142 else 143 m_predicates = null; 144 145 } 146 147 156 protected void initPredicateInfo(Compiler compiler, int opPos) 157 throws javax.xml.transform.TransformerException 158 { 159 160 int pos = compiler.getFirstPredicateOpPos(opPos); 161 162 if(pos > 0) 163 { 164 m_predicates = compiler.getCompiledPredicates(pos); 165 if(null != m_predicates) 166 { 167 for(int i = 0; i < m_predicates.length; i++) 168 { 169 m_predicates[i].exprSetParent(this); 170 } 171 } 172 } 173 } 174 175 183 public Expression getPredicate(int index) 184 { 185 return m_predicates[index]; 186 } 187 188 193 public int getProximityPosition() 194 { 195 196 return getProximityPosition(m_predicateIndex); 198 } 199 200 207 public int getProximityPosition(XPathContext xctxt) 208 { 209 return getProximityPosition(); 210 } 211 212 220 public abstract int getLastPos(XPathContext xctxt); 221 222 230 protected int getProximityPosition(int predicateIndex) 231 { 232 return (predicateIndex >= 0) ? m_proximityPositions[predicateIndex] : 0; 233 } 234 235 238 public void resetProximityPositions() 239 { 240 int nPredicates = getPredicateCount(); 241 if (nPredicates > 0) 242 { 243 if (null == m_proximityPositions) 244 m_proximityPositions = new int[nPredicates]; 245 246 for (int i = 0; i < nPredicates; i++) 247 { 248 try 249 { 250 initProximityPosition(i); 251 } 252 catch(Exception e) 253 { 254 throw new org.apache.xml.utils.WrappedRuntimeException(e); 256 } 257 } 258 } 259 } 260 261 268 public void initProximityPosition(int i) throws javax.xml.transform.TransformerException 269 { 270 m_proximityPositions[i] = 0; 271 } 272 273 279 protected void countProximityPosition(int i) 280 { 281 int[] pp = m_proximityPositions; 284 if ((null != pp) && (i < pp.length)) 285 pp[i]++; 286 } 287 288 293 public boolean isReverseAxes() 294 { 295 return false; 296 } 297 298 303 public int getPredicateIndex() 304 { 305 return m_predicateIndex; 306 } 307 308 318 boolean executePredicates(int context, XPathContext xctxt) 319 throws javax.xml.transform.TransformerException 320 { 321 322 int nPredicates = getPredicateCount(); 323 if (nPredicates == 0) 325 return true; 326 327 PrefixResolver savedResolver = xctxt.getNamespaceContext(); 328 329 try 330 { 331 m_predicateIndex = 0; 332 xctxt.pushSubContextList(this); 333 xctxt.pushNamespaceContext(m_lpi.getPrefixResolver()); 334 xctxt.pushCurrentNode(context); 335 336 for (int i = 0; i < nPredicates; i++) 337 { 338 XObject pred = m_predicates[i].execute(xctxt); 340 if (XObject.CLASS_NUMBER == pred.getType()) 343 { 344 if (DEBUG_PREDICATECOUNTING) 345 { 346 System.out.flush(); 347 System.out.println("\n===== start predicate count ========"); 348 System.out.println("m_predicateIndex: " + m_predicateIndex); 349 System.out.println("pred.num(): " + pred.num()); 352 } 353 354 int proxPos = this.getProximityPosition(m_predicateIndex); 355 int predIndex = (int) pred.num(); 356 if (proxPos != predIndex) 357 { 358 if (DEBUG_PREDICATECOUNTING) 359 { 360 System.out.println("\nnode context: "+nodeToString(context)); 361 System.out.println("index predicate is false: "+proxPos); 362 System.out.println("\n===== end predicate count ========"); 363 } 364 return false; 365 } 366 else if (DEBUG_PREDICATECOUNTING) 367 { 368 System.out.println("\nnode context: "+nodeToString(context)); 369 System.out.println("index predicate is true: "+proxPos); 370 System.out.println("\n===== end predicate count ========"); 371 } 372 373 if(m_predicates[i].isStableNumber() && i == nPredicates - 1) 383 { 384 m_foundLast = true; 385 } 386 } 387 else if (!pred.bool()) 388 return false; 389 390 countProximityPosition(++m_predicateIndex); 391 } 392 } 393 finally 394 { 395 xctxt.popCurrentNode(); 396 xctxt.popNamespaceContext(); 397 xctxt.popSubContextList(); 398 m_predicateIndex = -1; 399 } 400 401 return true; 402 } 403 404 414 public void fixupVariables(java.util.Vector vars, int globalsSize) 415 { 416 super.fixupVariables(vars, globalsSize); 417 418 int nPredicates = getPredicateCount(); 419 420 for (int i = 0; i < nPredicates; i++) 421 { 422 m_predicates[i].fixupVariables(vars, globalsSize); 423 } 424 } 425 426 427 434 protected String nodeToString(int n) 435 { 436 if(DTM.NULL != n) 437 { 438 DTM dtm = m_lpi.getXPathContext().getDTM(n); 439 return dtm.getNodeName(n) + "{" + (n+1) + "}"; 440 } 441 else 442 { 443 return "null"; 444 } 445 } 446 447 449 458 public short acceptNode(int n) 459 { 460 461 XPathContext xctxt = m_lpi.getXPathContext(); 462 463 try 464 { 465 xctxt.pushCurrentNode(n); 466 467 XObject score = execute(xctxt, n); 468 469 if (score != NodeTest.SCORE_NONE) 471 { 472 if (getPredicateCount() > 0) 473 { 474 countProximityPosition(0); 475 476 if (!executePredicates(n, xctxt)) 477 return DTMIterator.FILTER_SKIP; 478 } 479 480 return DTMIterator.FILTER_ACCEPT; 481 } 482 } 483 catch (javax.xml.transform.TransformerException se) 484 { 485 486 throw new RuntimeException (se.getMessage()); 488 } 489 finally 490 { 491 xctxt.popCurrentNode(); 492 } 493 494 return DTMIterator.FILTER_SKIP; 495 } 496 497 498 503 public LocPathIterator getLocPathIterator() 504 { 505 return m_lpi; 506 } 507 508 514 public void setLocPathIterator(LocPathIterator li) 515 { 516 m_lpi = li; 517 if(this != li) 518 li.exprSetParent(this); 519 } 520 521 527 public boolean canTraverseOutsideSubtree() 528 { 529 int n = getPredicateCount(); 530 for (int i = 0; i < n; i++) 531 { 532 if(getPredicate(i).canTraverseOutsideSubtree()) 533 return true; 534 } 535 return false; 536 } 537 538 547 public void callPredicateVisitors(XPathVisitor visitor) 548 { 549 if (null != m_predicates) 550 { 551 int n = m_predicates.length; 552 for (int i = 0; i < n; i++) 553 { 554 ExpressionOwner predOwner = new PredOwner(i); 555 if (visitor.visitPredicate(predOwner, m_predicates[i])) 556 { 557 m_predicates[i].callVisitors(predOwner, visitor); 558 } 559 560 } 561 } 562 } 563 564 567 public boolean deepEquals(Expression expr) 568 { 569 if (!super.deepEquals(expr)) 570 return false; 571 572 PredicatedNodeTest pnt = (PredicatedNodeTest) expr; 573 if (null != m_predicates) 574 { 575 576 int n = m_predicates.length; 577 if ((null == pnt.m_predicates) || (pnt.m_predicates.length != n)) 578 return false; 579 for (int i = 0; i < n; i++) 580 { 581 if (!m_predicates[i].deepEquals(pnt.m_predicates[i])) 582 return false; 583 } 584 } 585 else if (null != pnt.m_predicates) 586 return false; 587 588 return true; 589 } 590 591 592 transient protected boolean m_foundLast = false; 593 594 596 protected LocPathIterator m_lpi; 597 598 601 transient int m_predicateIndex = -1; 602 603 607 private Expression[] m_predicates; 608 609 613 transient protected int[] m_proximityPositions; 614 615 616 static final boolean DEBUG_PREDICATECOUNTING = false; 617 618 class PredOwner implements ExpressionOwner 619 { 620 int m_index; 621 622 PredOwner(int index) 623 { 624 m_index = index; 625 } 626 627 630 public Expression getExpression() 631 { 632 return m_predicates[m_index]; 633 } 634 635 636 639 public void setExpression(Expression exp) 640 { 641 exp.exprSetParent(PredicatedNodeTest.this); 642 m_predicates[m_index] = exp; 643 } 644 } 645 646 } 647 | Popular Tags |