1 16 19 package org.apache.xalan.templates; 20 21 import java.text.DecimalFormatSymbols ; 22 import java.util.Hashtable ; 23 import java.util.Properties ; 24 import java.util.Vector ; 25 26 import javax.xml.transform.ErrorListener ; 27 import javax.xml.transform.Templates ; 28 import javax.xml.transform.Transformer ; 29 import javax.xml.transform.TransformerConfigurationException ; 30 import javax.xml.transform.TransformerException ; 31 32 import org.apache.xalan.extensions.ExtensionNamespacesManager; 33 import org.apache.xalan.processor.XSLTSchema; 34 import org.apache.xalan.res.XSLMessages; 35 import org.apache.xalan.res.XSLTErrorResources; 36 37 import org.apache.xalan.transformer.TransformerImpl; 38 import org.apache.xml.dtm.DTM; 39 import org.apache.xml.dtm.ref.ExpandedNameTable; 40 import org.apache.xml.utils.IntStack; 41 import org.apache.xml.utils.QName; 42 import org.apache.xpath.XPath; 43 import org.apache.xpath.XPathContext; 44 45 49 public class StylesheetRoot extends StylesheetComposed 50 implements java.io.Serializable , Templates 51 { 52 53 57 public StylesheetRoot(ErrorListener errorListener) throws TransformerConfigurationException 58 { 59 60 super(null); 61 62 setStylesheetRoot(this); 63 64 try 65 { 66 m_selectDefault = new XPath("node()", this, this, XPath.SELECT, errorListener); 67 68 initDefaultRule(errorListener); 69 } 70 catch (TransformerException se) 71 { 72 throw new TransformerConfigurationException (XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_INIT_DEFAULT_TEMPLATES, null), se); } 74 } 75 76 80 private Hashtable m_availElems; 81 82 89 public StylesheetRoot(XSLTSchema schema, ErrorListener listener) throws TransformerConfigurationException 90 { 91 92 this(listener); 93 m_availElems = schema.getElemsAvailable(); 94 } 95 96 101 public boolean isRoot() 102 { 103 return true; 104 } 105 106 112 public Hashtable getAvailableElements() 113 { 114 return m_availElems; 115 } 116 117 private ExtensionNamespacesManager m_extNsMgr = null; 118 119 123 public ExtensionNamespacesManager getExtensionNamespacesManager() 124 { 125 if (m_extNsMgr == null) 126 m_extNsMgr = new ExtensionNamespacesManager(); 127 return m_extNsMgr; 128 } 129 130 135 public Vector getExtensions() 136 { 137 return m_extNsMgr != null ? m_extNsMgr.getExtensions() : null; 138 } 139 140 149 150 152 157 public Transformer newTransformer() 158 { 159 return new TransformerImpl(this); 160 } 161 162 163 public Properties getDefaultOutputProps() 164 { 165 return m_outputProperties.getProperties(); 166 } 167 168 179 public Properties getOutputProperties() 180 { 181 return (Properties )getDefaultOutputProps().clone(); 182 } 183 184 186 197 public void recompose() throws TransformerException 198 { 199 201 Vector recomposableElements = new Vector (); 202 203 205 if (null == m_globalImportList) 206 { 207 208 Vector importList = new Vector (); 209 210 addImports(this, true, importList); 211 212 218 m_globalImportList = new StylesheetComposed[importList.size()]; 219 220 for (int i = 0, j= importList.size() -1; i < importList.size(); i++) 221 { 222 m_globalImportList[j] = (StylesheetComposed) importList.elementAt(i); 223 m_globalImportList[j].recomposeIncludes(m_globalImportList[j]); 227 m_globalImportList[j--].recomposeImports(); 229 } 230 } 231 int n = getGlobalImportCount(); 233 234 for (int i = 0; i < n; i++) 235 { 236 StylesheetComposed imported = getGlobalImport(i); 237 imported.recompose(recomposableElements); 238 } 239 240 242 QuickSort2(recomposableElements, 0, recomposableElements.size() - 1); 243 244 246 247 m_outputProperties = new OutputProperties(org.apache.xml.serializer.Method.UNKNOWN); 248 250 m_attrSets = new Hashtable (); 251 m_decimalFormatSymbols = new Hashtable (); 252 m_keyDecls = new Vector (); 253 m_namespaceAliasComposed = new Hashtable (); 254 m_templateList = new TemplateList(); 255 m_variables = new Vector (); 256 257 for (int i = recomposableElements.size() - 1; i >= 0; i--) 262 ((ElemTemplateElement) recomposableElements.elementAt(i)).recompose(this); 263 264 268 272 279 initComposeState(); 280 281 m_templateList.compose(this); 283 284 m_outputProperties.compose(this); 286 m_outputProperties.endCompose(this); 287 288 291 n = getGlobalImportCount(); 292 293 for (int i = 0; i < n; i++) 294 { 295 StylesheetComposed imported = this.getGlobalImport(i); 296 int includedCount = imported.getIncludeCountComposed(); 297 for (int j = -1; j < includedCount; j++) 298 { 299 Stylesheet included = imported.getIncludeComposed(j); 300 composeTemplates(included); 301 } 302 } 303 if (m_extNsMgr != null) 305 m_extNsMgr.registerUnregisteredNamespaces(); 306 307 clearComposeState(); 308 } 309 310 317 void composeTemplates(ElemTemplateElement templ) throws TransformerException 318 { 319 320 templ.compose(this); 321 322 for (ElemTemplateElement child = templ.getFirstChildElem(); 323 child != null; child = child.getNextSiblingElem()) 324 { 325 composeTemplates(child); 326 } 327 328 templ.endCompose(this); 329 } 330 331 337 private StylesheetComposed[] m_globalImportList; 338 339 358 protected void addImports(Stylesheet stylesheet, boolean addToList, Vector importList) 359 { 360 361 363 int n = stylesheet.getImportCount(); 364 365 if (n > 0) 366 { 367 for (int i = 0; i < n; i++) 368 { 369 Stylesheet imported = stylesheet.getImport(i); 370 371 addImports(imported, true, importList); 372 } 373 } 374 375 n = stylesheet.getIncludeCount(); 376 377 if (n > 0) 378 { 379 for (int i = 0; i < n; i++) 380 { 381 Stylesheet included = stylesheet.getInclude(i); 382 383 addImports(included, false, importList); 384 } 385 } 386 387 if (addToList) 388 importList.addElement(stylesheet); 389 390 } 391 392 400 public StylesheetComposed getGlobalImport(int i) 401 { 402 return m_globalImportList[i]; 403 } 404 405 413 public int getGlobalImportCount() 414 { 415 return (m_globalImportList!=null) 416 ? m_globalImportList.length 417 : 1; 418 } 419 420 428 public int getImportNumber(StylesheetComposed sheet) 429 { 430 431 if (this == sheet) 432 return 0; 433 434 int n = getGlobalImportCount(); 435 436 for (int i = 0; i < n; i++) 437 { 438 if (sheet == getGlobalImport(i)) 439 return i; 440 } 441 442 return -1; 443 } 444 445 450 private OutputProperties m_outputProperties; 451 452 457 void recomposeOutput(OutputProperties oprops) 458 throws TransformerException 459 { 460 461 m_outputProperties.copyFrom(oprops); 462 } 463 464 475 public OutputProperties getOutputComposed() 476 { 477 478 return m_outputProperties; 481 } 482 483 485 private boolean m_outputMethodSet = false; 486 487 493 public boolean isOutputMethodSet() 494 { 495 return m_outputMethodSet; 496 } 497 498 503 private Hashtable m_attrSets; 504 505 510 void recomposeAttributeSets(ElemAttributeSet attrSet) 511 { 512 Vector attrSetList = (Vector ) m_attrSets.get(attrSet.getName()); 513 514 if (null == attrSetList) 515 { 516 attrSetList = new Vector (); 517 518 m_attrSets.put(attrSet.getName(), attrSetList); 519 } 520 521 attrSetList.addElement(attrSet); 522 } 523 524 534 public Vector getAttributeSetComposed(QName name) 535 throws ArrayIndexOutOfBoundsException 536 { 537 return (Vector ) m_attrSets.get(name); 538 } 539 540 544 private Hashtable m_decimalFormatSymbols; 545 546 551 void recomposeDecimalFormats(DecimalFormatProperties dfp) 552 { 553 DecimalFormatSymbols oldDfs = 554 (DecimalFormatSymbols ) m_decimalFormatSymbols.get(dfp.getName()); 555 if (null == oldDfs) 556 { 557 m_decimalFormatSymbols.put(dfp.getName(), dfp.getDecimalFormatSymbols()); 558 } 559 else if (!dfp.getDecimalFormatSymbols().equals(oldDfs)) 560 { 561 String themsg; 562 if (dfp.getName().equals(new QName(""))) 563 { 564 themsg = XSLMessages.createWarning( 566 XSLTErrorResources.WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED, 567 new Object [0]); 568 } 569 else 570 { 571 themsg = XSLMessages.createWarning( 573 XSLTErrorResources.WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE, 574 new Object [] {dfp.getName()}); 575 } 576 577 error(themsg); } 579 580 } 581 582 597 public DecimalFormatSymbols getDecimalFormatComposed(QName name) 598 { 599 return (DecimalFormatSymbols ) m_decimalFormatSymbols.get(name); 600 } 601 602 607 private Vector m_keyDecls; 608 609 614 void recomposeKeys(KeyDeclaration keyDecl) 615 { 616 m_keyDecls.addElement(keyDecl); 617 } 618 619 625 public Vector getKeysComposed() 626 { 627 return m_keyDecls; 628 } 629 630 634 private Hashtable m_namespaceAliasComposed; 635 636 641 void recomposeNamespaceAliases(NamespaceAlias nsAlias) 642 { 643 m_namespaceAliasComposed.put(nsAlias.getStylesheetNamespace(), 644 nsAlias); 645 } 646 647 656 public NamespaceAlias getNamespaceAliasComposed(String uri) 657 { 658 return (NamespaceAlias) ((null == m_namespaceAliasComposed) 659 ? null : m_namespaceAliasComposed.get(uri)); 660 } 661 662 666 private TemplateList m_templateList; 667 668 673 void recomposeTemplates(ElemTemplate template) 674 { 675 m_templateList.setTemplate(template); 676 } 677 678 684 public final TemplateList getTemplateListComposed() 685 { 686 return m_templateList; 687 } 688 689 696 public final void setTemplateListComposed(TemplateList templateList) 697 { 698 m_templateList = templateList; 699 } 700 701 716 public ElemTemplate getTemplateComposed(XPathContext xctxt, 717 int targetNode, 718 QName mode, 719 boolean quietConflictWarnings, 720 DTM dtm) 721 throws TransformerException 722 { 723 return m_templateList.getTemplate(xctxt, targetNode, mode, 724 quietConflictWarnings, 725 dtm); 726 } 727 728 747 public ElemTemplate getTemplateComposed(XPathContext xctxt, 748 int targetNode, 749 QName mode, 750 int maxImportLevel, int endImportLevel, 751 boolean quietConflictWarnings, 752 DTM dtm) 753 throws TransformerException 754 { 755 return m_templateList.getTemplate(xctxt, targetNode, mode, 756 maxImportLevel, endImportLevel, 757 quietConflictWarnings, 758 dtm); 759 } 760 761 770 public ElemTemplate getTemplateComposed(QName qname) 771 { 772 return m_templateList.getTemplate(qname); 773 } 774 775 779 private Vector m_variables; 780 781 786 void recomposeVariables(ElemVariable elemVar) 787 { 788 if (getVariableOrParamComposed(elemVar.getName()) == null) 790 { 791 elemVar.setIsTopLevel(true); elemVar.setIndex(m_variables.size()); 793 m_variables.addElement(elemVar); 794 } 795 } 796 797 805 public ElemVariable getVariableOrParamComposed(QName qname) 806 { 807 if (null != m_variables) 808 { 809 int n = m_variables.size(); 810 811 for (int i = 0; i < n; i++) 812 { 813 ElemVariable var = (ElemVariable)m_variables.elementAt(i); 814 if(var.getName().equals(qname)) 815 return var; 816 } 817 } 818 819 return null; 820 } 821 822 828 public Vector getVariablesAndParamsComposed() 829 { 830 return m_variables; 831 } 832 833 838 private TemplateList m_whiteSpaceInfoList; 839 840 845 void recomposeWhiteSpaceInfo(WhiteSpaceInfo wsi) 846 { 847 if (null == m_whiteSpaceInfoList) 848 m_whiteSpaceInfoList = new TemplateList(); 849 850 m_whiteSpaceInfoList.setTemplate(wsi); 851 } 852 853 860 public boolean shouldCheckWhitespace() 861 { 862 return null != m_whiteSpaceInfoList; 863 } 864 865 876 public WhiteSpaceInfo getWhiteSpaceInfo( 877 XPathContext support, int targetElement, DTM dtm) throws TransformerException 878 { 879 880 if (null != m_whiteSpaceInfoList) 881 return (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support, 882 targetElement, null, false, dtm); 883 else 884 return null; 885 } 886 887 898 public boolean shouldStripWhiteSpace( 899 XPathContext support, int targetElement) throws TransformerException 900 { 901 if (null != m_whiteSpaceInfoList) 902 { 903 while(DTM.NULL != targetElement) 904 { 905 DTM dtm = support.getDTM(targetElement); 906 WhiteSpaceInfo info = (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support, 907 targetElement, null, false, dtm); 908 if(null != info) 909 return info.getShouldStripSpace(); 910 911 int parent = dtm.getParent(targetElement); 912 if(DTM.NULL != parent && DTM.ELEMENT_NODE == dtm.getNodeType(parent)) 913 targetElement = parent; 914 else 915 targetElement = DTM.NULL; 916 } 917 } 918 return false; 919 } 920 921 927 public boolean canStripWhiteSpace() 928 { 929 return (null != m_whiteSpaceInfoList); 930 } 931 932 933 934 940 private ElemTemplate m_defaultTextRule; 941 942 948 public final ElemTemplate getDefaultTextRule() 949 { 950 return m_defaultTextRule; 951 } 952 953 959 private ElemTemplate m_defaultRule; 960 961 967 public final ElemTemplate getDefaultRule() 968 { 969 return m_defaultRule; 970 } 971 972 983 private ElemTemplate m_defaultRootRule; 984 985 991 public final ElemTemplate getDefaultRootRule() 992 { 993 return m_defaultRootRule; 994 } 995 996 1001 private ElemTemplate m_startRule; 1002 1003 1009 public final ElemTemplate getStartRule() 1010 { 1011 return m_startRule; 1012 } 1013 1014 1015 1019 XPath m_selectDefault; 1020 1021 1026 private void initDefaultRule(ErrorListener errorListener) throws TransformerException 1027 { 1028 1029 m_defaultRule = new ElemTemplate(); 1031 1032 m_defaultRule.setStylesheet(this); 1033 1034 XPath defMatch = new XPath("*", this, this, XPath.MATCH, errorListener); 1035 1036 m_defaultRule.setMatch(defMatch); 1037 1038 ElemApplyTemplates childrenElement = new ElemApplyTemplates(); 1039 1040 childrenElement.setIsDefaultTemplate(true); 1041 childrenElement.setSelect(m_selectDefault); 1042 m_defaultRule.appendChild(childrenElement); 1043 1044 m_startRule = m_defaultRule; 1045 1046 m_defaultTextRule = new ElemTemplate(); 1048 1049 m_defaultTextRule.setStylesheet(this); 1050 1051 defMatch = new XPath("text() | @*", this, this, XPath.MATCH, errorListener); 1052 1053 m_defaultTextRule.setMatch(defMatch); 1054 1055 ElemValueOf elemValueOf = new ElemValueOf(); 1056 1057 m_defaultTextRule.appendChild(elemValueOf); 1058 1059 XPath selectPattern = new XPath(".", this, this, XPath.SELECT, errorListener); 1060 1061 elemValueOf.setSelect(selectPattern); 1062 1063 m_defaultRootRule = new ElemTemplate(); 1065 1066 m_defaultRootRule.setStylesheet(this); 1067 1068 defMatch = new XPath("/", this, this, XPath.MATCH, errorListener); 1069 1070 m_defaultRootRule.setMatch(defMatch); 1071 1072 childrenElement = new ElemApplyTemplates(); 1073 1074 childrenElement.setIsDefaultTemplate(true); 1075 m_defaultRootRule.appendChild(childrenElement); 1076 childrenElement.setSelect(m_selectDefault); 1077 } 1078 1079 1097 1098 private void QuickSort2(Vector v, int lo0, int hi0) 1099 { 1100 int lo = lo0; 1101 int hi = hi0; 1102 1103 if ( hi0 > lo0) 1104 { 1105 ElemTemplateElement midNode = (ElemTemplateElement) v.elementAt( ( lo0 + hi0 ) / 2 ); 1108 1109 while( lo <= hi ) 1111 { 1112 while( (lo < hi0) && (((ElemTemplateElement) v.elementAt(lo)).compareTo(midNode) < 0) ) 1115 { 1116 ++lo; 1117 } 1119 while( (hi > lo0) && (((ElemTemplateElement) v.elementAt(hi)).compareTo(midNode) > 0) ) { 1122 --hi; 1123 } 1124 1125 if( lo <= hi ) 1127 { 1128 ElemTemplateElement node = (ElemTemplateElement) v.elementAt(lo); 1129 v.setElementAt(v.elementAt(hi), lo); 1130 v.setElementAt(node, hi); 1131 1132 ++lo; 1133 --hi; 1134 } 1135 } 1136 1137 if( lo0 < hi ) 1140 { 1141 QuickSort2( v, lo0, hi ); 1142 } 1143 1144 if( lo < hi0 ) 1147 { 1148 QuickSort2( v, lo, hi0 ); 1149 } 1150 } 1151 } 1153 private ComposeState m_composeState; 1154 1155 1158 void initComposeState() 1159 { 1160 m_composeState = new ComposeState(); 1161 } 1162 1163 1167 ComposeState getComposeState() 1168 { 1169 return m_composeState; 1170 } 1171 1172 1175 private void clearComposeState() 1176 { 1177 m_composeState = null; 1178 } 1179 1180 1183 class ComposeState 1184 { 1185 ComposeState() 1186 { 1187 int size = m_variables.size(); 1188 for (int i = 0; i < size; i++) 1189 { 1190 ElemVariable ev = (ElemVariable)m_variables.elementAt(i); 1191 m_variableNames.addElement(ev.getName()); 1192 } 1193 1194 } 1195 1196 private ExpandedNameTable m_ent = new ExpandedNameTable(); 1197 1198 1206 public int getQNameID(QName qname) 1207 { 1208 1209 return m_ent.getExpandedTypeID(qname.getNamespace(), 1210 qname.getLocalName(), 1211 org.apache.xml.dtm.DTM.ELEMENT_NODE); 1214 } 1215 1216 1220 private java.util.Vector m_variableNames = new java.util.Vector (); 1221 1222 1228 int addVariableName(final org.apache.xml.utils.QName qname) 1229 { 1230 int pos = m_variableNames.size(); 1231 m_variableNames.addElement(qname); 1232 int frameSize = m_variableNames.size() - getGlobalsSize(); 1233 if(frameSize > m_maxStackFrameSize) 1234 m_maxStackFrameSize++; 1235 return pos; 1236 } 1237 1238 void resetStackFrameSize() 1239 { 1240 m_maxStackFrameSize = 0; 1241 } 1242 1243 int getFrameSize() 1244 { 1245 return m_maxStackFrameSize; 1246 } 1247 1248 1253 int getCurrentStackFrameSize() 1254 { 1255 return m_variableNames.size(); 1256 } 1257 1258 1261 void setCurrentStackFrameSize(int sz) 1262 { 1263 m_variableNames.setSize(sz); 1264 } 1265 1266 int getGlobalsSize() 1267 { 1268 return m_variables.size(); 1269 } 1270 1271 IntStack m_marks = new IntStack(); 1272 1273 void pushStackMark() 1274 { 1275 m_marks.push(getCurrentStackFrameSize()); 1276 } 1277 1278 void popStackMark() 1279 { 1280 int mark = m_marks.pop(); 1281 setCurrentStackFrameSize(mark); 1282 } 1283 1284 1291 java.util.Vector getVariableNames() 1292 { 1293 return m_variableNames; 1294 } 1295 1296 private int m_maxStackFrameSize; 1297 1298 } 1299} 1300 | Popular Tags |