1 16 19 package org.apache.xalan.templates; 20 21 import java.util.Enumeration ; 22 import java.util.Hashtable ; 23 import java.util.Vector ; 24 25 import javax.xml.transform.TransformerException ; 26 27 import org.apache.xalan.res.XSLTErrorResources; 28 import org.apache.xml.dtm.DTM; 29 import org.apache.xml.utils.QName; 30 import org.apache.xpath.Expression; 31 import org.apache.xpath.XPath; 32 import org.apache.xpath.XPathContext; 33 import org.apache.xpath.compiler.PsuedoNames; 34 import org.apache.xpath.patterns.NodeTest; 35 import org.apache.xpath.patterns.StepPattern; 36 import org.apache.xpath.patterns.UnionPattern; 37 38 42 public class TemplateList implements java.io.Serializable 43 { 44 45 49 public TemplateList() 50 { 51 super(); 52 } 53 54 61 public void setTemplate(ElemTemplate template) 62 { 63 XPath matchXPath = template.getMatch(); 64 65 if (null == template.getName() && null == matchXPath) 66 { 67 template.error(XSLTErrorResources.ER_NEED_NAME_OR_MATCH_ATTRIB, 68 new Object []{ "xsl:template" }); 69 } 70 71 if (null != template.getName()) 72 { 73 ElemTemplate existingTemplate = (ElemTemplate) m_namedTemplates.get(template.getName()); 74 if (null == existingTemplate) 75 { 76 m_namedTemplates.put(template.getName(), template); 77 } 78 else 79 { 80 int existingPrecedence = 81 existingTemplate.getStylesheetComposed().getImportCountComposed(); 82 int newPrecedence = template.getStylesheetComposed().getImportCountComposed(); 83 if (newPrecedence > existingPrecedence) 84 { 85 m_namedTemplates.put(template.getName(), template); 87 } 88 else if (newPrecedence == existingPrecedence) 89 template.error(XSLTErrorResources.ER_DUPLICATE_NAMED_TEMPLATE, 90 new Object []{ template.getName() }); 91 } 92 } 93 94 95 96 if (null != matchXPath) 97 { 98 Expression matchExpr = matchXPath.getExpression(); 99 100 if (matchExpr instanceof StepPattern) 101 { 102 insertPatternInTable((StepPattern) matchExpr, template); 103 } 104 else if (matchExpr instanceof UnionPattern) 105 { 106 UnionPattern upat = (UnionPattern) matchExpr; 107 StepPattern[] pats = upat.getPatterns(); 108 int n = pats.length; 109 110 for (int i = 0; i < n; i++) 111 { 112 insertPatternInTable(pats[i], template); 113 } 114 } 115 else 116 { 117 118 } 120 } 121 } 122 123 124 static boolean DEBUG = false; 125 126 130 void dumpAssociationTables() 131 { 132 133 Enumeration associations = m_patternTable.elements(); 134 135 while (associations.hasMoreElements()) 136 { 137 TemplateSubPatternAssociation head = 138 (TemplateSubPatternAssociation) associations.nextElement(); 139 140 while (null != head) 141 { 142 System.out.print("(" + head.getTargetString() + ", " 143 + head.getPattern() + ")"); 144 145 head = head.getNext(); 146 } 147 148 System.out.println("\n....."); 149 } 150 151 TemplateSubPatternAssociation head = m_wildCardPatterns; 152 153 System.out.print("wild card list: "); 154 155 while (null != head) 156 { 157 System.out.print("(" + head.getTargetString() + ", " 158 + head.getPattern() + ")"); 159 160 head = head.getNext(); 161 } 162 163 System.out.println("\n....."); 164 } 165 166 170 public void compose(StylesheetRoot sroot) 171 { 172 173 if (DEBUG) 174 { 175 System.out.println("Before wildcard insert..."); 176 dumpAssociationTables(); 177 } 178 179 if (null != m_wildCardPatterns) 180 { 181 Enumeration associations = m_patternTable.elements(); 182 183 while (associations.hasMoreElements()) 184 { 185 TemplateSubPatternAssociation head = 186 (TemplateSubPatternAssociation) associations.nextElement(); 187 TemplateSubPatternAssociation wild = m_wildCardPatterns; 188 189 while (null != wild) 190 { 191 try 192 { 193 head = insertAssociationIntoList( 194 head, (TemplateSubPatternAssociation) wild.clone(), true); 195 } 196 catch (CloneNotSupportedException cnse){} 197 198 wild = wild.getNext(); 199 } 200 } 201 } 202 203 if (DEBUG) 204 { 205 System.out.println("After wildcard insert..."); 206 dumpAssociationTables(); 207 } 208 } 209 210 220 private TemplateSubPatternAssociation 221 insertAssociationIntoList(TemplateSubPatternAssociation head, 222 TemplateSubPatternAssociation item, 223 boolean isWildCardInsert) 224 { 225 226 230 double priority = getPriorityOrScore(item); 231 double workPriority; 232 int importLevel = item.getImportLevel(); 233 int docOrder = item.getDocOrderPos(); 234 TemplateSubPatternAssociation insertPoint = head; 235 TemplateSubPatternAssociation next; 236 boolean insertBefore; 240 250 while (true) 251 { 252 next = insertPoint.getNext(); 253 if (null == next) 254 break; 255 else 256 { 257 workPriority = getPriorityOrScore(next); 258 if (importLevel > next.getImportLevel()) 259 break; 260 else if (importLevel < next.getImportLevel()) 261 insertPoint = next; 262 else if (priority > workPriority) break; 264 else if (priority < workPriority) 265 insertPoint = next; 266 else if (docOrder >= next.getDocOrderPos()) break; 268 else 269 insertPoint = next; 270 } 271 } 272 273 if ( (null == next) || (insertPoint == head) ) { 275 workPriority = getPriorityOrScore(insertPoint); 276 if (importLevel > insertPoint.getImportLevel()) 277 insertBefore = true; 278 else if (importLevel < insertPoint.getImportLevel()) 279 insertBefore = false; 280 else if (priority > workPriority) 281 insertBefore = true; 282 else if (priority < workPriority) 283 insertBefore = false; 284 else if (docOrder >= insertPoint.getDocOrderPos()) 285 insertBefore = true; 286 else 287 insertBefore = false; 288 } 289 else 290 insertBefore = false; 291 292 294 if (isWildCardInsert) 295 { 296 if (insertBefore) 297 { 298 item.setNext(insertPoint); 299 300 String key = insertPoint.getTargetString(); 301 302 item.setTargetString(key); 303 putHead(key, item); 304 return item; 305 } 306 else 307 { 308 item.setNext(next); 309 insertPoint.setNext(item); 310 return head; 311 } 312 } 313 else 314 { 315 if (insertBefore) 316 { 317 item.setNext(insertPoint); 318 319 if (insertPoint.isWild() || item.isWild()) 320 m_wildCardPatterns = item; 321 else 322 putHead(item.getTargetString(), item); 323 return item; 324 } 325 else 326 { 327 item.setNext(next); 328 insertPoint.setNext(item); 329 return head; 330 } 331 } 332 } 333 334 340 private void insertPatternInTable(StepPattern pattern, ElemTemplate template) 341 { 342 343 String target = pattern.getTargetString(); 344 345 if (null != target) 346 { 347 String pstring = template.getMatch().getPatternString(); 348 TemplateSubPatternAssociation association = 349 new TemplateSubPatternAssociation(template, pattern, pstring); 350 351 boolean isWildCard = association.isWild(); 353 TemplateSubPatternAssociation head = isWildCard 354 ? m_wildCardPatterns 355 : getHead(target); 356 357 if (null == head) 358 { 359 if (isWildCard) 360 m_wildCardPatterns = association; 361 else 362 putHead(target, association); 363 } 364 else 365 { 366 insertAssociationIntoList(head, association, false); 367 } 368 } 369 } 370 371 386 private double getPriorityOrScore(TemplateSubPatternAssociation matchPat) 387 { 388 389 double priority = matchPat.getTemplate().getPriority(); 390 391 if (priority == XPath.MATCH_SCORE_NONE) 392 { 393 Expression ex = matchPat.getStepPattern(); 394 395 if (ex instanceof NodeTest) 396 { 397 return ((NodeTest) ex).getDefaultScore(); 398 } 399 } 400 401 return priority; 402 } 403 404 411 public ElemTemplate getTemplate(QName qname) 412 { 413 return (ElemTemplate) m_namedTemplates.get(qname); 414 } 415 416 427 public TemplateSubPatternAssociation getHead(XPathContext xctxt, 428 int targetNode, DTM dtm) 429 { 430 short targetNodeType = dtm.getNodeType(targetNode); 431 TemplateSubPatternAssociation head; 432 433 switch (targetNodeType) 434 { 435 case DTM.ELEMENT_NODE : 436 case DTM.ATTRIBUTE_NODE : 437 head = (TemplateSubPatternAssociation) m_patternTable.get( 438 dtm.getLocalName(targetNode)); 439 break; 440 case DTM.TEXT_NODE : 441 case DTM.CDATA_SECTION_NODE : 442 head = m_textPatterns; 443 break; 444 case DTM.ENTITY_REFERENCE_NODE : 445 case DTM.ENTITY_NODE : 446 head = (TemplateSubPatternAssociation) m_patternTable.get( 447 dtm.getNodeName(targetNode)); break; 449 case DTM.PROCESSING_INSTRUCTION_NODE : 450 head = (TemplateSubPatternAssociation) m_patternTable.get( 451 dtm.getLocalName(targetNode)); 452 break; 453 case DTM.COMMENT_NODE : 454 head = m_commentPatterns; 455 break; 456 case DTM.DOCUMENT_NODE : 457 case DTM.DOCUMENT_FRAGMENT_NODE : 458 head = m_docPatterns; 459 break; 460 case DTM.NOTATION_NODE : 461 default : 462 head = (TemplateSubPatternAssociation) m_patternTable.get( 463 dtm.getNodeName(targetNode)); } 465 466 return (null == head) ? m_wildCardPatterns : head; 467 } 468 469 489 public ElemTemplate getTemplateFast(XPathContext xctxt, 490 int targetNode, 491 int expTypeID, 492 QName mode, 493 int maxImportLevel, 494 boolean quietConflictWarnings, 495 DTM dtm) 496 throws TransformerException 497 { 498 499 TemplateSubPatternAssociation head; 500 501 switch (dtm.getNodeType(targetNode)) 502 { 503 case DTM.ELEMENT_NODE : 504 case DTM.ATTRIBUTE_NODE : 505 head = (TemplateSubPatternAssociation) m_patternTable.get( 506 dtm.getLocalNameFromExpandedNameID(expTypeID)); 507 break; 508 case DTM.TEXT_NODE : 509 case DTM.CDATA_SECTION_NODE : 510 head = m_textPatterns; 511 break; 512 case DTM.ENTITY_REFERENCE_NODE : 513 case DTM.ENTITY_NODE : 514 head = (TemplateSubPatternAssociation) m_patternTable.get( 515 dtm.getNodeName(targetNode)); break; 517 case DTM.PROCESSING_INSTRUCTION_NODE : 518 head = (TemplateSubPatternAssociation) m_patternTable.get( 519 dtm.getLocalName(targetNode)); 520 break; 521 case DTM.COMMENT_NODE : 522 head = m_commentPatterns; 523 break; 524 case DTM.DOCUMENT_NODE : 525 case DTM.DOCUMENT_FRAGMENT_NODE : 526 head = m_docPatterns; 527 break; 528 case DTM.NOTATION_NODE : 529 default : 530 head = (TemplateSubPatternAssociation) m_patternTable.get( 531 dtm.getNodeName(targetNode)); } 533 534 if(null == head) 535 { 536 head = m_wildCardPatterns; 537 if(null == head) 538 return null; 539 } 540 541 xctxt.pushNamespaceContextNull(); 545 try 546 { 547 do 548 { 549 if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel) ) 550 { 551 continue; 552 } 553 ElemTemplate template = head.getTemplate(); 554 xctxt.setNamespaceContext(template); 555 556 if ((head.m_stepPattern.execute(xctxt, targetNode, dtm, expTypeID) != NodeTest.SCORE_NONE) 557 && head.matchMode(mode)) 558 { 559 if (quietConflictWarnings) 560 checkConflicts(head, xctxt, targetNode, mode); 561 562 return template; 563 } 564 } 565 while (null != (head = head.getNext())); 566 } 567 finally 568 { 569 xctxt.popNamespaceContext(); 570 } 571 572 return null; 573 } 575 590 public ElemTemplate getTemplate(XPathContext xctxt, 591 int targetNode, 592 QName mode, 593 boolean quietConflictWarnings, 594 DTM dtm) 595 throws TransformerException 596 { 597 598 TemplateSubPatternAssociation head = getHead(xctxt, targetNode, dtm); 599 600 if (null != head) 601 { 602 xctxt.pushNamespaceContextNull(); 606 xctxt.pushCurrentNodeAndExpression(targetNode, targetNode); 607 try 608 { 609 do 610 { 611 ElemTemplate template = head.getTemplate(); 612 xctxt.setNamespaceContext(template); 613 614 if ((head.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE) 615 && head.matchMode(mode)) 616 { 617 if (quietConflictWarnings) 618 checkConflicts(head, xctxt, targetNode, mode); 619 620 return template; 621 } 622 } 623 while (null != (head = head.getNext())); 624 } 625 finally 626 { 627 xctxt.popCurrentNodeAndExpression(); 628 xctxt.popNamespaceContext(); 629 } 630 } 631 632 return null; 633 } 635 654 public ElemTemplate getTemplate(XPathContext xctxt, 655 int targetNode, 656 QName mode, 657 int maxImportLevel, int endImportLevel, 658 boolean quietConflictWarnings, 659 DTM dtm) 660 throws TransformerException 661 { 662 663 TemplateSubPatternAssociation head = getHead(xctxt, targetNode, dtm); 664 665 if (null != head) 666 { 667 xctxt.pushNamespaceContextNull(); 671 xctxt.pushCurrentNodeAndExpression(targetNode, targetNode); 672 try 673 { 674 do 675 { 676 if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel)) 677 { 678 continue; 679 } 680 if (head.getImportLevel()<= maxImportLevel - endImportLevel) 681 return null; 682 ElemTemplate template = head.getTemplate(); 683 xctxt.setNamespaceContext(template); 684 685 if ((head.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE) 686 && head.matchMode(mode)) 687 { 688 if (quietConflictWarnings) 689 checkConflicts(head, xctxt, targetNode, mode); 690 691 return template; 692 } 693 } 694 while (null != (head = head.getNext())); 695 } 696 finally 697 { 698 xctxt.popCurrentNodeAndExpression(); 699 xctxt.popNamespaceContext(); 700 } 701 } 702 703 return null; 704 } 706 710 public TemplateWalker getWalker() 711 { 712 return new TemplateWalker(); 713 } 714 715 723 private void checkConflicts(TemplateSubPatternAssociation head, 724 XPathContext xctxt, int targetNode, QName mode) 725 { 726 727 } 729 730 736 private void addObjectIfNotFound(Object obj, Vector v) 737 { 738 739 int n = v.size(); 740 boolean addIt = true; 741 742 for (int i = 0; i < n; i++) 743 { 744 if (v.elementAt(i) == obj) 745 { 746 addIt = false; 747 748 break; 749 } 750 } 751 752 if (addIt) 753 { 754 v.addElement(obj); 755 } 756 } 757 758 765 private Hashtable m_namedTemplates = new Hashtable (89); 766 767 774 private Hashtable m_patternTable = new Hashtable (89); 775 776 778 private TemplateSubPatternAssociation m_wildCardPatterns = null; 779 780 782 private TemplateSubPatternAssociation m_textPatterns = null; 783 784 786 private TemplateSubPatternAssociation m_docPatterns = null; 787 788 790 private TemplateSubPatternAssociation m_commentPatterns = null; 791 792 801 private Hashtable getNamedTemplates() 802 { 803 return m_namedTemplates; 804 } 805 806 815 private void setNamedTemplates(Hashtable v) 816 { 817 m_namedTemplates = v; 818 } 819 820 828 private TemplateSubPatternAssociation getHead(String key) 829 { 830 return (TemplateSubPatternAssociation) m_patternTable.get(key); 831 } 832 833 839 private void putHead(String key, TemplateSubPatternAssociation assoc) 840 { 841 842 if (key.equals(PsuedoNames.PSEUDONAME_TEXT)) 843 m_textPatterns = assoc; 844 else if (key.equals(PsuedoNames.PSEUDONAME_ROOT)) 845 m_docPatterns = assoc; 846 else if (key.equals(PsuedoNames.PSEUDONAME_COMMENT)) 847 m_commentPatterns = assoc; 848 849 m_patternTable.put(key, assoc); 850 } 851 852 857 public class TemplateWalker 858 { 859 private Enumeration hashIterator; 860 private boolean inPatterns; 861 private TemplateSubPatternAssociation curPattern; 862 863 private Hashtable m_compilerCache = new Hashtable (); 864 865 private TemplateWalker() 866 { 867 hashIterator = m_patternTable.elements(); 868 inPatterns = true; 869 curPattern = null; 870 } 871 872 public ElemTemplate next() 873 { 874 875 ElemTemplate retValue = null; 876 ElemTemplate ct; 877 878 while (true) 879 { 880 if (inPatterns) 881 { 882 if (null != curPattern) 883 curPattern = curPattern.getNext(); 884 885 if (null != curPattern) 886 retValue = curPattern.getTemplate(); 887 else 888 { 889 if (hashIterator.hasMoreElements()) 890 { 891 curPattern = (TemplateSubPatternAssociation) hashIterator.nextElement(); 892 retValue = curPattern.getTemplate(); 893 } 894 else 895 { 896 inPatterns = false; 897 hashIterator = m_namedTemplates.elements(); 898 } 899 } 900 } 901 902 if (!inPatterns) 903 { 904 if (hashIterator.hasMoreElements()) 905 retValue = (ElemTemplate) hashIterator.nextElement(); 906 else 907 return null; 908 } 909 910 ct = (ElemTemplate) m_compilerCache.get(new Integer (retValue.getUid())); 911 if (null == ct) 912 { 913 m_compilerCache.put(new Integer (retValue.getUid()), retValue); 914 return retValue; 915 } 916 } 917 } 918 } 919 920 } 921 | Popular Tags |