1 16 19 package org.apache.xalan.templates; 20 21 import java.util.Vector ; 22 23 import org.apache.xalan.res.XSLMessages; 24 import org.apache.xalan.res.XSLTErrorResources; 25 import org.apache.xml.utils.QName; 26 import org.apache.xml.utils.WrappedRuntimeException; 27 import org.apache.xpath.Expression; 28 import org.apache.xpath.ExpressionNode; 29 import org.apache.xpath.ExpressionOwner; 30 import org.apache.xpath.XPath; 31 import org.apache.xpath.axes.AxesWalker; 32 import org.apache.xpath.axes.FilterExprIteratorSimple; 33 import org.apache.xpath.axes.FilterExprWalker; 34 import org.apache.xpath.axes.LocPathIterator; 35 import org.apache.xpath.axes.SelfIteratorNoPredicate; 36 import org.apache.xpath.axes.WalkerFactory; 37 import org.apache.xpath.axes.WalkingIterator; 38 import org.apache.xpath.operations.Variable; 39 import org.apache.xpath.operations.VariableSafeAbsRef; 40 41 47 public class RedundentExprEliminator extends XSLTVisitor 48 { 49 Vector m_paths; 50 Vector m_absPaths; 51 boolean m_isSameContext; 52 AbsPathChecker m_absPathChecker = new AbsPathChecker(); 53 54 static int m_uniquePsuedoVarID = 1; 55 static final String PSUEDOVARNAMESPACE = Constants.S_VENDORURL+"/xalan/psuedovar"; 56 57 public static boolean DEBUG = false; 58 public static boolean DIAGNOSE_NUM_PATHS_REDUCED = false; 59 public static boolean DIAGNOSE_MULTISTEPLIST = false; 60 61 64 VarNameCollector m_varNameCollector = new VarNameCollector(); 65 66 73 public RedundentExprEliminator() 74 { 75 m_isSameContext = true; 76 m_absPaths = new Vector (); 77 m_paths = null; 78 } 79 80 81 92 public void eleminateRedundentLocals(ElemTemplateElement psuedoVarRecipient) 93 { 94 eleminateRedundent(psuedoVarRecipient, m_paths); 95 } 96 97 108 public void eleminateRedundentGlobals(StylesheetRoot stylesheet) 109 { 110 eleminateRedundent(stylesheet, m_absPaths); 111 } 112 113 114 126 protected void eleminateRedundent(ElemTemplateElement psuedoVarRecipient, Vector paths) 127 { 128 int n = paths.size(); 129 int numPathsEliminated = 0; 130 int numUniquePathsEliminated = 0; 131 for (int i = 0; i < n; i++) 132 { 133 ExpressionOwner owner = (ExpressionOwner) paths.elementAt(i); 134 if (null != owner) 135 { 136 int found = findAndEliminateRedundant(i + 1, i, owner, psuedoVarRecipient, paths); 137 if (found > 0) 138 numUniquePathsEliminated++; 139 numPathsEliminated += found; 140 } 141 } 142 143 eleminateSharedPartialPaths(psuedoVarRecipient, paths); 144 145 if(DIAGNOSE_NUM_PATHS_REDUCED) 146 diagnoseNumPaths(paths, numPathsEliminated, numUniquePathsEliminated); 147 } 148 149 157 protected void eleminateSharedPartialPaths(ElemTemplateElement psuedoVarRecipient, Vector paths) 158 { 159 MultistepExprHolder list = createMultistepExprList(paths); 160 if(null != list) 161 { 162 if(DIAGNOSE_MULTISTEPLIST) 163 list.diagnose(); 164 165 boolean isGlobal = (paths == m_absPaths); 166 167 int longestStepsCount = list.m_stepCount; 170 for (int i = longestStepsCount-1; i >= 1; i--) 171 { 172 MultistepExprHolder next = list; 173 while(null != next) 174 { 175 if(next.m_stepCount < i) 176 break; 177 list = matchAndEliminatePartialPaths(next, list, isGlobal, i, psuedoVarRecipient); 178 next = next.m_next; 179 } 180 } 181 } 182 } 183 184 191 protected MultistepExprHolder matchAndEliminatePartialPaths(MultistepExprHolder testee, 192 MultistepExprHolder head, 193 boolean isGlobal, 194 int lengthToTest, 195 ElemTemplateElement varScope) 196 { 197 if(null == testee.m_exprOwner) 198 return head; 199 200 WalkingIterator iter1 = (WalkingIterator) testee.m_exprOwner.getExpression(); 202 if(partialIsVariable(testee, lengthToTest)) 203 return head; 204 MultistepExprHolder matchedPaths = null; 205 MultistepExprHolder matchedPathsTail = null; 206 MultistepExprHolder meh = head; 207 while( null != meh) 208 { 209 if ((meh != testee) && (null != meh.m_exprOwner)) 210 { 211 WalkingIterator iter2 = (WalkingIterator) meh.m_exprOwner.getExpression(); 212 if (stepsEqual(iter1, iter2, lengthToTest)) 213 { 214 if (null == matchedPaths) 215 { 216 try 217 { 218 matchedPaths = (MultistepExprHolder)testee.clone(); 219 testee.m_exprOwner = null; } 221 catch(CloneNotSupportedException cnse){} 222 matchedPathsTail = matchedPaths; 223 matchedPathsTail.m_next = null; 224 } 225 226 try 227 { 228 matchedPathsTail.m_next = (MultistepExprHolder)meh.clone(); 229 meh.m_exprOwner = null; } 231 catch(CloneNotSupportedException cnse){} 232 matchedPathsTail = matchedPathsTail.m_next; 233 matchedPathsTail.m_next = null; 234 } 235 } 236 meh = meh.m_next; 237 } 238 239 int matchCount = 0; 240 if(null != matchedPaths) 241 { 242 ElemTemplateElement root = isGlobal ? varScope : findCommonAncestor(matchedPaths); 243 WalkingIterator sharedIter = (WalkingIterator)matchedPaths.m_exprOwner.getExpression(); 244 WalkingIterator newIter = createIteratorFromSteps(sharedIter, lengthToTest); 245 ElemVariable var = createPsuedoVarDecl(root, newIter, isGlobal); 246 if(DIAGNOSE_MULTISTEPLIST) 247 System.err.println("Created var: "+var.getName()+(isGlobal ? "(Global)" : "")); 248 while(null != matchedPaths) 249 { 250 ExpressionOwner owner = matchedPaths.m_exprOwner; 251 WalkingIterator iter = (WalkingIterator)owner.getExpression(); 252 253 if(DIAGNOSE_MULTISTEPLIST) 254 diagnoseLineNumber(iter); 255 256 LocPathIterator newIter2 = 257 changePartToRef(var.getName(), iter, lengthToTest, isGlobal); 258 owner.setExpression(newIter2); 259 260 matchedPaths = matchedPaths.m_next; 261 } 262 } 263 264 if(DIAGNOSE_MULTISTEPLIST) 265 diagnoseMultistepList(matchCount, lengthToTest, isGlobal); 266 return head; 267 } 268 269 273 boolean partialIsVariable(MultistepExprHolder testee, int lengthToTest) 274 { 275 if(1 == lengthToTest) 276 { 277 WalkingIterator wi = (WalkingIterator)testee.m_exprOwner.getExpression(); 278 if(wi.getFirstWalker() instanceof FilterExprWalker) 279 return true; 280 } 281 return false; 282 } 283 284 287 protected void diagnoseLineNumber(Expression expr) 288 { 289 ElemTemplateElement e = getElemFromExpression(expr); 290 System.err.println(" " + e.getSystemId() + " Line " + e.getLineNumber()); 291 } 292 293 297 protected ElemTemplateElement findCommonAncestor(MultistepExprHolder head) 298 { 299 int numExprs = head.getLength(); 301 ElemTemplateElement[] elems = new ElemTemplateElement[numExprs]; 305 int[] ancestorCounts = new int[numExprs]; 306 307 MultistepExprHolder next = head; 310 int shortestAncestorCount = 10000; 311 for(int i = 0; i < numExprs; i++) 312 { 313 ElemTemplateElement elem = 314 getElemFromExpression(next.m_exprOwner.getExpression()); 315 elems[i] = elem; 316 int numAncestors = countAncestors(elem); 317 ancestorCounts[i] = numAncestors; 318 if(numAncestors < shortestAncestorCount) 319 { 320 shortestAncestorCount = numAncestors; 321 } 322 next = next.m_next; 323 } 324 325 for(int i = 0; i < numExprs; i++) 327 { 328 if(ancestorCounts[i] > shortestAncestorCount) 329 { 330 int numStepCorrection = ancestorCounts[i] - shortestAncestorCount; 331 for(int j = 0; j < numStepCorrection; j++) 332 { 333 elems[i] = elems[i].getParentElem(); 334 } 335 } 336 } 337 338 ElemTemplateElement first = null; 341 while(shortestAncestorCount-- >= 0) 342 { 343 boolean areEqual = true; 344 first = elems[0]; 345 for(int i = 1; i < numExprs; i++) 346 { 347 if(first != elems[i]) 348 { 349 areEqual = false; 350 break; 351 } 352 } 353 if(areEqual && isNotSameAsOwner(head, first) && first.canAcceptVariables()) 356 { 357 if(DIAGNOSE_MULTISTEPLIST) 358 { 359 System.err.print(first.getClass().getName()); 360 System.err.println(" at " + first.getSystemId() + " Line " + first.getLineNumber()); 361 } 362 return first; 363 } 364 365 for(int i = 0; i < numExprs; i++) 366 { 367 elems[i] = elems[i].getParentElem(); 368 } 369 } 370 371 assertion(false, "Could not find common ancestor!!!"); 372 return null; 373 } 374 375 387 protected boolean isNotSameAsOwner(MultistepExprHolder head, ElemTemplateElement ete) 388 { 389 MultistepExprHolder next = head; 390 while(null != next) 391 { 392 ElemTemplateElement elemOwner = getElemFromExpression(next.m_exprOwner.getExpression()); 393 if(elemOwner == ete) 394 return false; 395 next = next.m_next; 396 } 397 return true; 398 } 399 400 406 protected int countAncestors(ElemTemplateElement elem) 407 { 408 int count = 0; 409 while(null != elem) 410 { 411 count++; 412 elem = elem.getParentElem(); 413 } 414 return count; 415 } 416 417 420 protected void diagnoseMultistepList( 421 int matchCount, 422 int lengthToTest, 423 boolean isGlobal) 424 { 425 if (matchCount > 0) 426 { 427 System.err.print( 428 "Found multistep matches: " + matchCount + ", " + lengthToTest + " length"); 429 if (isGlobal) 430 System.err.println(" (global)"); 431 else 432 System.err.println(); 433 } 434 } 435 436 444 protected LocPathIterator changePartToRef(final QName uniquePsuedoVarName, WalkingIterator wi, 445 final int numSteps, final boolean isGlobal) 446 { 447 Variable var = new Variable(); 448 var.setQName(uniquePsuedoVarName); 449 var.setIsGlobal(isGlobal); 450 if(isGlobal) 451 { ElemTemplateElement elem = getElemFromExpression(wi); 452 StylesheetRoot root = elem.getStylesheetRoot(); 453 Vector vars = root.getVariablesAndParamsComposed(); 454 var.setIndex(vars.size()-1); 455 } 456 457 AxesWalker walker = wi.getFirstWalker(); 459 for(int i = 0; i < numSteps; i++) 460 { 461 assertion(null != walker, "Walker should not be null!"); 462 walker = walker.getNextWalker(); 463 } 464 465 if(null != walker) 466 { 467 468 FilterExprWalker few = new FilterExprWalker(wi); 469 few.setInnerExpression(var); 470 few.exprSetParent(wi); 471 few.setNextWalker(walker); 472 walker.setPrevWalker(few); 473 wi.setFirstWalker(few); 474 return wi; 475 } 476 else 477 { 478 FilterExprIteratorSimple feis = new FilterExprIteratorSimple(var); 479 feis.exprSetParent(wi.exprGetParent()); 480 return feis; 481 } 482 } 483 484 492 protected WalkingIterator createIteratorFromSteps(final WalkingIterator wi, int numSteps) 493 { 494 WalkingIterator newIter = new WalkingIterator(wi.getPrefixResolver()); 495 try 496 { 497 AxesWalker walker = (AxesWalker)wi.getFirstWalker().clone(); 498 newIter.setFirstWalker(walker); 499 walker.setLocPathIterator(newIter); 500 for(int i = 1; i < numSteps; i++) 501 { 502 AxesWalker next = (AxesWalker)walker.getNextWalker().clone(); 503 walker.setNextWalker(next); 504 next.setLocPathIterator(newIter); 505 walker = next; 506 } 507 walker.setNextWalker(null); 508 } 509 catch(CloneNotSupportedException cnse) 510 { 511 throw new WrappedRuntimeException(cnse); 512 } 513 return newIter; 514 } 515 516 525 protected boolean stepsEqual(WalkingIterator iter1, WalkingIterator iter2, 526 int numSteps) 527 { 528 AxesWalker aw1 = iter1.getFirstWalker(); 529 AxesWalker aw2 = iter2.getFirstWalker(); 530 531 for(int i = 0; (i < numSteps); i++) 532 { 533 if((null == aw1) || (null == aw2)) 534 return false; 535 536 if(!aw1.deepEquals(aw2)) 537 return false; 538 539 aw1 = aw1.getNextWalker(); 540 aw2 = aw2.getNextWalker(); 541 } 542 543 assertion((null != aw1) || (null != aw2), "Total match is incorrect!"); 544 545 return true; 546 } 547 548 559 protected MultistepExprHolder createMultistepExprList(Vector paths) 560 { 561 MultistepExprHolder first = null; 562 int n = paths.size(); 563 for(int i = 0; i < n; i++) 564 { 565 ExpressionOwner eo = (ExpressionOwner)paths.elementAt(i); 566 if(null == eo) 567 continue; 568 569 LocPathIterator lpi = (LocPathIterator)eo.getExpression(); 571 int numPaths = countSteps(lpi); 572 if(numPaths > 1) 573 { 574 if(null == first) 575 first = new MultistepExprHolder(eo, numPaths, null); 576 else 577 first = first.addInSortedOrder(eo, numPaths); 578 } 579 } 580 581 if((null == first) || (first.getLength() <= 1)) 582 return null; 583 else 584 return first; 585 } 586 587 601 protected int findAndEliminateRedundant(int start, int firstOccuranceIndex, 602 ExpressionOwner firstOccuranceOwner, 603 ElemTemplateElement psuedoVarRecipient, 604 Vector paths) 605 throws org.w3c.dom.DOMException 606 { 607 MultistepExprHolder head = null; 608 MultistepExprHolder tail = null; 609 int numPathsFound = 0; 610 int n = paths.size(); 611 612 Expression expr1 = firstOccuranceOwner.getExpression(); 613 if(DEBUG) 614 assertIsLocPathIterator(expr1, firstOccuranceOwner); 615 boolean isGlobal = (paths == m_absPaths); 616 LocPathIterator lpi = (LocPathIterator)expr1; 617 int stepCount = countSteps(lpi); 618 for(int j = start; j < n; j++) 619 { 620 ExpressionOwner owner2 = (ExpressionOwner)paths.elementAt(j); 621 if(null != owner2) 622 { 623 Expression expr2 = owner2.getExpression(); 624 boolean isEqual = expr2.deepEquals(lpi); 625 if(isEqual) 626 { 627 LocPathIterator lpi2 = (LocPathIterator)expr2; 628 if(null == head) 629 { 630 head = new MultistepExprHolder(firstOccuranceOwner, stepCount, null); 631 tail = head; 632 numPathsFound++; 633 } 634 tail.m_next = new MultistepExprHolder(owner2, stepCount, null); 635 tail = tail.m_next; 636 637 paths.setElementAt(null, j); 639 640 numPathsFound++; 642 } 643 } 644 } 645 646 if((0 == numPathsFound) && isGlobal) 648 { 649 head = new MultistepExprHolder(firstOccuranceOwner, stepCount, null); 650 numPathsFound++; 651 } 652 653 if(null != head) 654 { 655 ElemTemplateElement root = isGlobal ? psuedoVarRecipient : findCommonAncestor(head); 656 LocPathIterator sharedIter = (LocPathIterator)head.m_exprOwner.getExpression(); 657 ElemVariable var = createPsuedoVarDecl(root, sharedIter, isGlobal); 658 if(DIAGNOSE_MULTISTEPLIST) 659 System.err.println("Created var: "+var.getName()+(isGlobal ? "(Global)" : "")); 660 QName uniquePsuedoVarName = var.getName(); 661 while(null != head) 662 { 663 ExpressionOwner owner = head.m_exprOwner; 664 if(DIAGNOSE_MULTISTEPLIST) 665 diagnoseLineNumber(owner.getExpression()); 666 changeToVarRef(uniquePsuedoVarName, owner, paths, root); 667 head = head.m_next; 668 } 669 paths.setElementAt(var.getSelect(), firstOccuranceIndex); 672 } 673 674 return numPathsFound; 675 } 676 677 680 protected int oldFindAndEliminateRedundant(int start, int firstOccuranceIndex, 681 ExpressionOwner firstOccuranceOwner, 682 ElemTemplateElement psuedoVarRecipient, 683 Vector paths) 684 throws org.w3c.dom.DOMException 685 { 686 QName uniquePsuedoVarName = null; 687 boolean foundFirst = false; 688 int numPathsFound = 0; 689 int n = paths.size(); 690 Expression expr1 = firstOccuranceOwner.getExpression(); 691 if(DEBUG) 692 assertIsLocPathIterator(expr1, firstOccuranceOwner); 693 boolean isGlobal = (paths == m_absPaths); 694 LocPathIterator lpi = (LocPathIterator)expr1; 695 for(int j = start; j < n; j++) 696 { 697 ExpressionOwner owner2 = (ExpressionOwner)paths.elementAt(j); 698 if(null != owner2) 699 { 700 Expression expr2 = owner2.getExpression(); 701 boolean isEqual = expr2.deepEquals(lpi); 702 if(isEqual) 703 { 704 LocPathIterator lpi2 = (LocPathIterator)expr2; 705 if(!foundFirst) 706 { 707 foundFirst = true; 708 ElemVariable var = createPsuedoVarDecl(psuedoVarRecipient, lpi, isGlobal); 712 if(null == var) 713 return 0; 714 uniquePsuedoVarName = var.getName(); 715 716 changeToVarRef(uniquePsuedoVarName, firstOccuranceOwner, 717 paths, psuedoVarRecipient); 718 719 paths.setElementAt(var.getSelect(), firstOccuranceIndex); 722 numPathsFound++; 723 } 724 725 changeToVarRef(uniquePsuedoVarName, owner2, paths, psuedoVarRecipient); 726 727 paths.setElementAt(null, j); 729 730 numPathsFound++; 732 } 733 } 734 } 735 736 if((0 == numPathsFound) && (paths == m_absPaths)) 738 { 739 ElemVariable var = createPsuedoVarDecl(psuedoVarRecipient, lpi, true); 740 if(null == var) 741 return 0; 742 uniquePsuedoVarName = var.getName(); 743 changeToVarRef(uniquePsuedoVarName, firstOccuranceOwner, paths, psuedoVarRecipient); 744 paths.setElementAt(var.getSelect(), firstOccuranceIndex); 745 numPathsFound++; 746 } 747 return numPathsFound; 748 } 749 750 756 protected int countSteps(LocPathIterator lpi) 757 { 758 if(lpi instanceof WalkingIterator) 759 { 760 WalkingIterator wi = (WalkingIterator)lpi; 761 AxesWalker aw = wi.getFirstWalker(); 762 int count = 0; 763 while(null != aw) 764 { 765 count++; 766 aw = aw.getNextWalker(); 767 } 768 return count; 769 } 770 else 771 return 1; 772 } 773 774 790 protected void changeToVarRef(QName varName, ExpressionOwner owner, 791 Vector paths, ElemTemplateElement psuedoVarRecipient) 792 { 793 Variable varRef = (paths == m_absPaths) ? new VariableSafeAbsRef() : new Variable(); 794 varRef.setQName(varName); 795 if(paths == m_absPaths) 796 { 797 StylesheetRoot root = (StylesheetRoot)psuedoVarRecipient; 798 Vector globalVars = root.getVariablesAndParamsComposed(); 799 varRef.setIndex(globalVars.size()-1); 802 varRef.setIsGlobal(true); 803 } 804 owner.setExpression(varRef); 805 } 806 807 817 protected ElemVariable createPsuedoVarDecl( 818 ElemTemplateElement psuedoVarRecipient, 819 LocPathIterator lpi, boolean isGlobal) 820 throws org.w3c.dom.DOMException 821 { 822 QName uniquePsuedoVarName = new QName (PSUEDOVARNAMESPACE, "#"+m_uniquePsuedoVarID); 823 m_uniquePsuedoVarID++; 824 825 if(isGlobal) 826 { 827 return createGlobalPsuedoVarDecl(uniquePsuedoVarName, 828 (StylesheetRoot)psuedoVarRecipient, lpi); 829 } 830 else 831 return createLocalPsuedoVarDecl(uniquePsuedoVarName, psuedoVarRecipient, lpi); 832 } 833 834 845 protected ElemVariable createGlobalPsuedoVarDecl(QName uniquePsuedoVarName, 846 StylesheetRoot stylesheetRoot, 847 LocPathIterator lpi) 848 throws org.w3c.dom.DOMException 849 { 850 ElemVariable psuedoVar = new ElemVariable(); 851 psuedoVar.setIsTopLevel(true); 852 XPath xpath = new XPath(lpi); 853 psuedoVar.setSelect(xpath); 854 psuedoVar.setName(uniquePsuedoVarName); 855 856 Vector globalVars = stylesheetRoot.getVariablesAndParamsComposed(); 857 psuedoVar.setIndex(globalVars.size()); 858 globalVars.addElement(psuedoVar); 859 return psuedoVar; 860 } 861 862 863 864 865 877 protected ElemVariable createLocalPsuedoVarDecl(QName uniquePsuedoVarName, 878 ElemTemplateElement psuedoVarRecipient, 879 LocPathIterator lpi) 880 throws org.w3c.dom.DOMException 881 { 882 ElemVariable psuedoVar = new ElemVariablePsuedo(); 883 884 XPath xpath = new XPath(lpi); 885 psuedoVar.setSelect(xpath); 886 psuedoVar.setName(uniquePsuedoVarName); 887 888 ElemVariable var = addVarDeclToElem(psuedoVarRecipient, lpi, psuedoVar); 889 890 lpi.exprSetParent(var); 891 892 return var; 893 } 894 895 898 protected ElemVariable addVarDeclToElem( 899 ElemTemplateElement psuedoVarRecipient, 900 LocPathIterator lpi, 901 ElemVariable psuedoVar) 902 throws org.w3c.dom.DOMException 903 { 904 ElemTemplateElement ete = psuedoVarRecipient.getFirstChildElem(); 906 907 lpi.callVisitors(null, m_varNameCollector); 908 909 if (m_varNameCollector.getVarCount() > 0) 914 { 915 ElemTemplateElement baseElem = getElemFromExpression(lpi); 916 ElemVariable varElem = getPrevVariableElem(baseElem); 917 while (null != varElem) 918 { 919 if (m_varNameCollector.doesOccur(varElem.getName())) 920 { 921 psuedoVarRecipient = varElem.getParentElem(); 922 ete = varElem.getNextSiblingElem(); 923 break; 924 } 925 varElem = getPrevVariableElem(varElem); 926 } 927 } 928 929 if ((null != ete) && (Constants.ELEMNAME_PARAMVARIABLE == ete.getXSLToken())) 930 { 931 if(isParam(lpi)) 933 return null; 934 935 while (null != ete) 936 { 937 ete = ete.getNextSiblingElem(); 938 if ((null != ete) && Constants.ELEMNAME_PARAMVARIABLE != ete.getXSLToken()) 939 break; 940 } 941 } 942 psuedoVarRecipient.insertBefore(psuedoVar, ete); 943 m_varNameCollector.reset(); 944 return psuedoVar; 945 } 946 947 950 protected boolean isParam(ExpressionNode expr) 951 { 952 while(null != expr) 953 { 954 if(expr instanceof ElemTemplateElement) 955 break; 956 expr = expr.exprGetParent(); 957 } 958 if(null != expr) 959 { 960 ElemTemplateElement ete = (ElemTemplateElement)expr; 961 while(null != ete) 962 { 963 int type = ete.getXSLToken(); 964 switch(type) 965 { 966 case Constants.ELEMNAME_PARAMVARIABLE: 967 return true; 968 case Constants.ELEMNAME_TEMPLATE: 969 case Constants.ELEMNAME_STYLESHEET: 970 return false; 971 } 972 ete = ete.getParentElem(); 973 } 974 } 975 return false; 976 977 } 978 979 988 protected ElemVariable getPrevVariableElem(ElemTemplateElement elem) 989 { 990 while(null != (elem = getPrevElementWithinContext(elem))) 993 { 994 int type = elem.getXSLToken(); 995 996 if((Constants.ELEMNAME_VARIABLE == type) || 997 (Constants.ELEMNAME_PARAMVARIABLE == type)) 998 { 999 return (ElemVariable)elem; 1000 } 1001 } 1002 return null; 1003 } 1004 1005 1013 protected ElemTemplateElement getPrevElementWithinContext(ElemTemplateElement elem) 1014 { 1015 ElemTemplateElement prev = elem.getPreviousSiblingElem(); 1016 if(null == prev) 1017 prev = elem.getParentElem(); 1018 if(null != prev) 1019 { 1020 int type = prev.getXSLToken(); 1021 if((Constants.ELEMNAME_FOREACH == type) || 1022 (Constants.ELEMNAME_TEMPLATE == type) || 1023 (Constants.ELEMNAME_STYLESHEET == type)) 1024 { 1025 prev = null; 1026 } 1027 } 1028 return prev; 1029 } 1030 1031 1039 protected ElemTemplateElement getElemFromExpression(Expression expr) 1040 { 1041 ExpressionNode parent = expr.exprGetParent(); 1042 while(null != parent) 1043 { 1044 if(parent instanceof ElemTemplateElement) 1045 return (ElemTemplateElement)parent; 1046 parent = parent.exprGetParent(); 1047 } 1048 throw new RuntimeException (XSLMessages.createMessage(XSLTErrorResources.ER_ASSERT_NO_TEMPLATE_PARENT, null)); 1049 } 1051 1052 1058 public boolean isAbsolute(LocPathIterator path) 1059 { 1060 int analysis = path.getAnalysisBits(); 1061 boolean isAbs = (WalkerFactory.isSet(analysis, WalkerFactory.BIT_ROOT) || 1062 WalkerFactory.isSet(analysis, WalkerFactory.BIT_ANY_DESCENDANT_FROM_ROOT)); 1063 if(isAbs) 1064 { 1065 isAbs = m_absPathChecker.checkAbsolute(path); 1066 } 1067 return isAbs; 1068 } 1069 1070 1071 1078 public boolean visitLocationPath(ExpressionOwner owner, LocPathIterator path) 1079 { 1080 if(path instanceof SelfIteratorNoPredicate) 1083 { 1084 return true; 1085 } 1086 else if(path instanceof WalkingIterator) 1087 { 1088 WalkingIterator wi = (WalkingIterator)path; 1089 AxesWalker aw = wi.getFirstWalker(); 1090 if((aw instanceof FilterExprWalker) && (null == aw.getNextWalker())) 1091 { 1092 FilterExprWalker few = (FilterExprWalker)aw; 1093 Expression exp = few.getInnerExpression(); 1094 if(exp instanceof Variable) 1095 return true; 1096 } 1097 } 1098 1099 if (isAbsolute(path) && (null != m_absPaths)) 1100 { 1101 if(DEBUG) 1102 validateNewAddition(m_absPaths, owner, path); 1103 m_absPaths.addElement(owner); 1104 } 1105 else if (m_isSameContext && (null != m_paths)) 1106 { 1107 if(DEBUG) 1108 validateNewAddition(m_paths, owner, path); 1109 m_paths.addElement(owner); 1110 } 1111 1112 return true; 1113 } 1114 1115 1125 public boolean visitPredicate(ExpressionOwner owner, Expression pred) 1126 { 1127 boolean savedIsSame = m_isSameContext; 1128 m_isSameContext = false; 1129 1130 pred.callVisitors(owner, this); 1132 1133 m_isSameContext = savedIsSame; 1134 1135 return false; 1138 } 1139 1140 1146 public boolean visitTopLevelInstruction(ElemTemplateElement elem) 1147 { 1148 int type = elem.getXSLToken(); 1149 switch(type) 1150 { 1151 case Constants.ELEMNAME_TEMPLATE : 1152 return visitInstruction(elem); 1153 default: 1154 return true; 1155 } 1156 } 1157 1158 1159 1166 public boolean visitInstruction(ElemTemplateElement elem) 1167 { 1168 int type = elem.getXSLToken(); 1169 switch (type) 1170 { 1171 case Constants.ELEMNAME_CALLTEMPLATE : 1172 case Constants.ELEMNAME_TEMPLATE : 1173 case Constants.ELEMNAME_FOREACH : 1174 { 1175 1176 if(type == Constants.ELEMNAME_FOREACH) 1178 { 1179 ElemForEach efe = (ElemForEach) elem; 1180 1181 Expression select = efe.getSelect(); 1182 select.callVisitors(efe, this); 1183 } 1184 1185 Vector savedPaths = m_paths; 1186 m_paths = new Vector (); 1187 1188 elem.callChildVisitors(this, false); 1192 eleminateRedundentLocals(elem); 1193 1194 m_paths = savedPaths; 1195 1196 return false; 1198 } 1199 case Constants.ELEMNAME_NUMBER : 1200 case Constants.ELEMNAME_SORT : 1201 boolean savedIsSame = m_isSameContext; 1204 m_isSameContext = false; 1205 elem.callChildVisitors(this); 1206 m_isSameContext = savedIsSame; 1207 return false; 1208 1209 default : 1210 return true; 1211 } 1212 } 1213 1214 1216 1219 protected void diagnoseNumPaths(Vector paths, int numPathsEliminated, 1220 int numUniquePathsEliminated) 1221 { 1222 if (numPathsEliminated > 0) 1223 { 1224 if(paths == m_paths) 1225 { 1226 System.err.println("Eliminated " + numPathsEliminated + " total paths!"); 1227 System.err.println( 1228 "Consolodated " + numUniquePathsEliminated + " redundent paths!"); 1229 } 1230 else 1231 { 1232 System.err.println("Eliminated " + numPathsEliminated + " total global paths!"); 1233 System.err.println( 1234 "Consolodated " + numUniquePathsEliminated + " redundent global paths!"); 1235 } 1236 } 1237 } 1238 1239 1240 1244 private final void assertIsLocPathIterator(Expression expr1, ExpressionOwner eo) 1245 throws RuntimeException 1246 { 1247 if(!(expr1 instanceof LocPathIterator)) 1248 { 1249 String errMsg; 1250 if(expr1 instanceof Variable) 1251 { 1252 errMsg = "Programmer's assertion: expr1 not an iterator: "+ 1253 ((Variable)expr1).getQName(); 1254 } 1255 else 1256 { 1257 errMsg = "Programmer's assertion: expr1 not an iterator: "+ 1258 expr1.getClass().getName(); 1259 } 1260 throw new RuntimeException (errMsg + ", "+ 1261 eo.getClass().getName()+" "+ 1262 expr1.exprGetParent()); 1263 } 1264 } 1265 1266 1267 1271 private static void validateNewAddition(Vector paths, ExpressionOwner owner, 1272 LocPathIterator path) 1273 throws RuntimeException 1274 { 1275 assertion(owner.getExpression() == path, "owner.getExpression() != path!!!"); 1276 int n = paths.size(); 1277 for(int i = 0; i < n; i++) 1279 { 1280 ExpressionOwner ew = (ExpressionOwner)paths.elementAt(i); 1281 assertion(ew != owner, "duplicate owner on the list!!!"); 1282 assertion(ew.getExpression() != path, "duplicate expression on the list!!!"); 1283 } 1284 } 1285 1286 1289 protected static void assertion(boolean b, String msg) 1290 { 1291 if(!b) 1292 { 1293 throw new RuntimeException (XSLMessages.createMessage(XSLTErrorResources.ER_ASSERT_REDUNDENT_EXPR_ELIMINATOR, new Object []{msg})); 1294 } 1296 } 1297 1298 1302 class MultistepExprHolder implements Cloneable 1303 { 1304 ExpressionOwner m_exprOwner; final int m_stepCount; 1306 MultistepExprHolder m_next; 1307 1308 1311 public Object clone() 1312 throws CloneNotSupportedException 1313 { 1314 return super.clone(); 1315 } 1316 1317 1324 MultistepExprHolder(ExpressionOwner exprOwner, int stepCount, MultistepExprHolder next) 1325 { 1326 m_exprOwner = exprOwner; 1327 assertion(null != m_exprOwner, "exprOwner can not be null!"); 1328 m_stepCount = stepCount; 1329 m_next = next; 1330 } 1331 1332 1340 MultistepExprHolder addInSortedOrder(ExpressionOwner exprOwner, int stepCount) 1341 { 1342 MultistepExprHolder first = this; 1343 MultistepExprHolder next = this; 1344 MultistepExprHolder prev = null; 1345 while(null != next) 1346 { 1347 if(stepCount >= next.m_stepCount) 1348 { 1349 MultistepExprHolder newholder = new MultistepExprHolder(exprOwner, stepCount, next); 1350 if(null == prev) 1351 first = newholder; 1352 else 1353 prev.m_next = newholder; 1354 1355 return first; 1356 } 1357 prev = next; 1358 next = next.m_next; 1359 } 1360 1361 prev.m_next = new MultistepExprHolder(exprOwner, stepCount, null); 1362 return first; 1363 } 1364 1365 1375 MultistepExprHolder unlink(MultistepExprHolder itemToRemove) 1376 { 1377 MultistepExprHolder first = this; 1378 MultistepExprHolder next = this; 1379 MultistepExprHolder prev = null; 1380 while(null != next) 1381 { 1382 if(next == itemToRemove) 1383 { 1384 if(null == prev) 1385 first = next.m_next; 1386 else 1387 prev.m_next = next.m_next; 1388 1389 next.m_next = null; 1390 1391 return first; 1392 } 1393 prev = next; 1394 next = next.m_next; 1395 } 1396 1397 assertion(false, "unlink failed!!!"); 1398 return null; 1399 } 1400 1401 1404 int getLength() 1405 { 1406 int count = 0; 1407 MultistepExprHolder next = this; 1408 while(null != next) 1409 { 1410 count++; 1411 next = next.m_next; 1412 } 1413 return count; 1414 } 1415 1416 1419 protected void diagnose() 1420 { 1421 System.err.print("Found multistep iterators: " + this.getLength() + " "); 1422 MultistepExprHolder next = this; 1423 while (null != next) 1424 { 1425 System.err.print("" + next.m_stepCount); 1426 next = next.m_next; 1427 if (null != next) 1428 System.err.print(", "); 1429 } 1430 System.err.println(); 1431 } 1432 1433 } 1434 1435} 1436 | Popular Tags |