1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.net.URL ; 23 import java.net.MalformedURLException ; 24 25 import java.util.Vector ; 26 import java.util.Enumeration ; 27 import java.util.Hashtable ; 28 import java.util.Iterator ; 29 import java.util.Properties ; 30 import java.util.StringTokenizer ; 31 32 import com.sun.org.apache.xml.internal.utils.SystemIDResolver; 33 import com.sun.org.apache.bcel.internal.generic.ANEWARRAY; 34 import com.sun.org.apache.bcel.internal.generic.BasicType; 35 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 36 import com.sun.org.apache.bcel.internal.generic.FieldGen; 37 import com.sun.org.apache.bcel.internal.generic.GETFIELD; 38 import com.sun.org.apache.bcel.internal.generic.GETSTATIC; 39 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 40 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 41 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 42 import com.sun.org.apache.bcel.internal.generic.ISTORE; 43 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 44 import com.sun.org.apache.bcel.internal.generic.InstructionList; 45 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 46 import com.sun.org.apache.bcel.internal.generic.NEW; 47 import com.sun.org.apache.bcel.internal.generic.NEWARRAY; 48 import com.sun.org.apache.bcel.internal.generic.PUSH; 49 import com.sun.org.apache.bcel.internal.generic.PUTFIELD; 50 import com.sun.org.apache.bcel.internal.generic.PUTSTATIC; 51 import com.sun.org.apache.bcel.internal.generic.TargetLostException; 52 import com.sun.org.apache.bcel.internal.util.InstructionFinder; 53 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 54 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 55 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 56 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 57 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 58 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 59 import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 60 import com.sun.org.apache.xml.internal.dtm.DTM; 61 62 67 public final class Stylesheet extends SyntaxTreeNode { 68 69 72 private String _version; 73 74 77 private QName _name; 78 79 82 private String _systemId; 83 84 87 private Stylesheet _parentStylesheet; 88 89 92 private Vector _globals = new Vector (); 93 94 97 private Boolean _hasLocalParams = null; 98 99 102 private String _className; 103 104 107 private final Vector _templates = new Vector (); 108 109 113 private Vector _allValidTemplates = null; 114 115 118 private int _nextModeSerial = 1; 119 120 123 private final Hashtable _modes = new Hashtable (); 124 125 128 private Mode _defaultMode; 129 130 133 private final Hashtable _extensions = new Hashtable (); 134 135 139 public Stylesheet _importedFrom = null; 140 141 145 public Stylesheet _includedFrom = null; 146 147 150 private Vector _includedStylesheets = null; 151 152 155 private int _importPrecedence = 1; 156 157 161 private int _minimumDescendantPrecedence = -1; 162 163 166 private Hashtable _keys = new Hashtable (); 167 168 172 private SourceLoader _loader = null; 173 174 177 private boolean _numberFormattingUsed = false; 178 179 183 private boolean _simplified = false; 184 185 188 private boolean _multiDocument = false; 189 190 193 private boolean _callsNodeset = false; 194 195 198 private boolean _hasIdCall = false; 199 200 203 private boolean _templateInlining = true; 204 205 208 private Output _lastOutputElement = null; 209 210 213 private Properties _outputProperties = null; 214 215 219 private int _outputMethod = UNKNOWN_OUTPUT; 220 221 public static final int UNKNOWN_OUTPUT = 0; 223 public static final int XML_OUTPUT = 1; 224 public static final int HTML_OUTPUT = 2; 225 public static final int TEXT_OUTPUT = 3; 226 227 230 public int getOutputMethod() { 231 return _outputMethod; 232 } 233 234 237 private void checkOutputMethod() { 238 if (_lastOutputElement != null) { 239 String method = _lastOutputElement.getOutputMethod(); 240 if (method != null) { 241 if (method.equals("xml")) 242 _outputMethod = XML_OUTPUT; 243 else if (method.equals("html")) 244 _outputMethod = HTML_OUTPUT; 245 else if (method.equals("text")) 246 _outputMethod = TEXT_OUTPUT; 247 } 248 } 249 } 250 251 public boolean getTemplateInlining() { 252 return _templateInlining; 253 } 254 255 public void setTemplateInlining(boolean flag) { 256 _templateInlining = flag; 257 } 258 259 public boolean isSimplified() { 260 return(_simplified); 261 } 262 263 public void setSimplified() { 264 _simplified = true; 265 } 266 267 public void setHasIdCall(boolean flag) { 268 _hasIdCall = flag; 269 } 270 271 public void setOutputProperty(String key, String value) { 272 if (_outputProperties == null) { 273 _outputProperties = new Properties (); 274 } 275 _outputProperties.setProperty(key, value); 276 } 277 278 public void setOutputProperties(Properties props) { 279 _outputProperties = props; 280 } 281 282 public Properties getOutputProperties() { 283 return _outputProperties; 284 } 285 286 public Output getLastOutputElement() { 287 return _lastOutputElement; 288 } 289 290 public void setMultiDocument(boolean flag) { 291 _multiDocument = flag; 292 } 293 294 public boolean isMultiDocument() { 295 return _multiDocument; 296 } 297 298 public void setCallsNodeset(boolean flag) { 299 if (flag) setMultiDocument(flag); 300 _callsNodeset = flag; 301 } 302 303 public boolean callsNodeset() { 304 return _callsNodeset; 305 } 306 307 public void numberFormattingUsed() { 308 _numberFormattingUsed = true; 309 315 Stylesheet parent = getParentStylesheet(); 316 if (null != parent) parent.numberFormattingUsed(); 317 } 318 319 public void setImportPrecedence(final int precedence) { 320 _importPrecedence = precedence; 322 323 final Enumeration elements = elements(); 325 while (elements.hasMoreElements()) { 326 SyntaxTreeNode child = (SyntaxTreeNode)elements.nextElement(); 327 if (child instanceof Include) { 328 Stylesheet included = ((Include)child).getIncludedStylesheet(); 329 if (included != null && included._includedFrom == this) { 330 included.setImportPrecedence(precedence); 331 } 332 } 333 } 334 335 if (_importedFrom != null) { 337 if (_importedFrom.getImportPrecedence() < precedence) { 338 final Parser parser = getParser(); 339 final int nextPrecedence = parser.getNextImportPrecedence(); 340 _importedFrom.setImportPrecedence(nextPrecedence); 341 } 342 } 343 else if (_includedFrom != null) { 345 if (_includedFrom.getImportPrecedence() != precedence) 346 _includedFrom.setImportPrecedence(precedence); 347 } 348 } 349 350 public int getImportPrecedence() { 351 return _importPrecedence; 352 } 353 354 359 public int getMinimumDescendantPrecedence() { 360 if (_minimumDescendantPrecedence == -1) { 361 int min = getImportPrecedence(); 363 364 final int inclImpCount = (_includedStylesheets != null) 366 ? _includedStylesheets.size() 367 : 0; 368 369 for (int i = 0; i < inclImpCount; i++) { 370 int prec = ((Stylesheet)_includedStylesheets.elementAt(i)) 371 .getMinimumDescendantPrecedence(); 372 373 if (prec < min) { 374 min = prec; 375 } 376 } 377 378 _minimumDescendantPrecedence = min; 379 } 380 return _minimumDescendantPrecedence; 381 } 382 383 public boolean checkForLoop(String systemId) { 384 if (_systemId != null && _systemId.equals(systemId)) { 386 return true; 387 } 388 if (_parentStylesheet != null) 390 return _parentStylesheet.checkForLoop(systemId); 391 return false; 393 } 394 395 public void setParser(Parser parser) { 396 super.setParser(parser); 397 _name = makeStylesheetName("__stylesheet_"); 398 } 399 400 public void setParentStylesheet(Stylesheet parent) { 401 _parentStylesheet = parent; 402 } 403 404 public Stylesheet getParentStylesheet() { 405 return _parentStylesheet; 406 } 407 408 public void setImportingStylesheet(Stylesheet parent) { 409 _importedFrom = parent; 410 parent.addIncludedStylesheet(this); 411 } 412 413 public void setIncludingStylesheet(Stylesheet parent) { 414 _includedFrom = parent; 415 parent.addIncludedStylesheet(this); 416 } 417 418 public void addIncludedStylesheet(Stylesheet child) { 419 if (_includedStylesheets == null) { 420 _includedStylesheets = new Vector (); 421 } 422 _includedStylesheets.addElement(child); 423 } 424 425 public void setSystemId(String systemId) { 426 if (systemId != null) { 427 _systemId = SystemIDResolver.getAbsoluteURI(systemId); 428 } 429 } 430 431 public String getSystemId() { 432 return _systemId; 433 } 434 435 public void setSourceLoader(SourceLoader loader) { 436 _loader = loader; 437 } 438 439 public SourceLoader getSourceLoader() { 440 return _loader; 441 } 442 443 private QName makeStylesheetName(String prefix) { 444 return getParser().getQName(prefix+getXSLTC().nextStylesheetSerial()); 445 } 446 447 450 public boolean hasGlobals() { 451 return _globals.size() > 0; 452 } 453 454 459 public boolean hasLocalParams() { 460 if (_hasLocalParams == null) { 461 Vector templates = getAllValidTemplates(); 462 final int n = templates.size(); 463 for (int i = 0; i < n; i++) { 464 final Template template = (Template)templates.elementAt(i); 465 if (template.hasParams()) { 466 _hasLocalParams = new Boolean (true); 467 return true; 468 } 469 } 470 _hasLocalParams = new Boolean (false); 471 return false; 472 } 473 else { 474 return _hasLocalParams.booleanValue(); 475 } 476 } 477 478 483 protected void addPrefixMapping(String prefix, String uri) { 484 if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return; 485 super.addPrefixMapping(prefix, uri); 486 } 487 488 491 private void extensionURI(String prefixes, SymbolTable stable) { 492 if (prefixes != null) { 493 StringTokenizer tokens = new StringTokenizer (prefixes); 494 while (tokens.hasMoreTokens()) { 495 final String prefix = tokens.nextToken(); 496 final String uri = lookupNamespace(prefix); 497 if (uri != null) { 498 _extensions.put(uri, prefix); 499 } 500 } 501 } 502 } 503 504 public boolean isExtension(String uri) { 505 return (_extensions.get(uri) != null); 506 } 507 508 public void excludeExtensionPrefixes(Parser parser) { 509 final SymbolTable stable = parser.getSymbolTable(); 510 final String excludePrefixes = getAttribute("exclude-result-prefixes"); 511 final String extensionPrefixes = getAttribute("extension-element-prefixes"); 512 513 stable.excludeURI(Constants.XSLT_URI); 515 stable.excludeNamespaces(excludePrefixes); 516 stable.excludeNamespaces(extensionPrefixes); 517 extensionURI(extensionPrefixes, stable); 518 } 519 520 525 public void parseContents(Parser parser) { 526 final SymbolTable stable = parser.getSymbolTable(); 527 528 538 539 addPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace"); 541 542 final Stylesheet sheet = stable.addStylesheet(_name, this); 544 if (sheet != null) { 545 ErrorMsg err = new ErrorMsg(ErrorMsg.MULTIPLE_STYLESHEET_ERR,this); 547 parser.reportError(Constants.ERROR, err); 548 } 549 550 if (_simplified) { 556 stable.excludeURI(XSLT_URI); 557 Template template = new Template(); 558 template.parseSimplified(this, parser); 559 } 560 else { 562 parseOwnChildren(parser); 563 } 564 } 565 566 569 public final void parseOwnChildren(Parser parser) { 570 final Vector contents = getContents(); 571 final int count = contents.size(); 572 573 for (int i = 0; i < count; i++) { 576 SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); 577 if ((child instanceof VariableBase) || 578 (child instanceof NamespaceAlias)) { 579 parser.getSymbolTable().setCurrentNode(child); 580 child.parseContents(parser); 581 } 582 } 583 584 for (int i = 0; i < count; i++) { 586 SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); 587 if (!(child instanceof VariableBase) && 588 !(child instanceof NamespaceAlias)) { 589 parser.getSymbolTable().setCurrentNode(child); 590 child.parseContents(parser); 591 } 592 593 if (!_templateInlining && (child instanceof Template)) { 596 Template template = (Template)child; 597 String name = "template$dot$" + template.getPosition(); 598 template.setName(parser.getQName(name)); 599 } 600 } 601 } 602 603 public void processModes() { 604 if (_defaultMode == null) 605 _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); 606 _defaultMode.processPatterns(_keys); 607 final Enumeration modes = _modes.elements(); 608 while (modes.hasMoreElements()) { 609 final Mode mode = (Mode)modes.nextElement(); 610 mode.processPatterns(_keys); 611 } 612 } 613 614 private void compileModes(ClassGenerator classGen) { 615 _defaultMode.compileApplyTemplates(classGen); 616 final Enumeration modes = _modes.elements(); 617 while (modes.hasMoreElements()) { 618 final Mode mode = (Mode)modes.nextElement(); 619 mode.compileApplyTemplates(classGen); 620 } 621 } 622 623 public Mode getMode(QName modeName) { 624 if (modeName == null) { 625 if (_defaultMode == null) { 626 _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); 627 } 628 return _defaultMode; 629 } 630 else { 631 Mode mode = (Mode)_modes.get(modeName); 632 if (mode == null) { 633 final String suffix = Integer.toString(_nextModeSerial++); 634 _modes.put(modeName, mode = new Mode(modeName, this, suffix)); 635 } 636 return mode; 637 } 638 } 639 640 643 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 644 final int count = _globals.size(); 645 for (int i = 0; i < count; i++) { 646 final VariableBase var = (VariableBase)_globals.elementAt(i); 647 var.typeCheck(stable); 648 } 649 return typeCheckContents(stable); 650 } 651 652 655 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 656 translate(); 657 } 658 659 private void addDOMField(ClassGenerator classGen) { 660 final FieldGen fgen = new FieldGen(ACC_PUBLIC, 661 Util.getJCRefType(DOM_INTF_SIG), 662 DOM_FIELD, 663 classGen.getConstantPool()); 664 classGen.addField(fgen.getField()); 665 } 666 667 670 private void addStaticField(ClassGenerator classGen, String type, 671 String name) 672 { 673 final FieldGen fgen = new FieldGen(ACC_PROTECTED|ACC_STATIC, 674 Util.getJCRefType(type), 675 name, 676 classGen.getConstantPool()); 677 classGen.addField(fgen.getField()); 678 679 } 680 681 684 public void translate() { 685 _className = getXSLTC().getClassName(); 686 687 final ClassGenerator classGen = 689 new ClassGenerator(_className, 690 TRANSLET_CLASS, 691 Constants.EMPTYSTRING, 692 ACC_PUBLIC | ACC_SUPER, 693 null, this); 694 695 addDOMField(classGen); 696 697 compileTransform(classGen); 700 701 final Enumeration elements = elements(); 703 while (elements.hasMoreElements()) { 704 Object element = elements.nextElement(); 705 if (element instanceof Template) { 707 final Template template = (Template)element; 709 getMode(template.getModeName()).addTemplate(template); 711 } 712 else if (element instanceof AttributeSet) { 714 ((AttributeSet)element).translate(classGen, null); 715 } 716 else if (element instanceof Output) { 717 Output output = (Output)element; 719 if (output.enabled()) _lastOutputElement = output; 720 } 721 else { 722 } 726 } 727 728 checkOutputMethod(); 729 processModes(); 730 compileModes(classGen); 731 compileStaticInitializer(classGen); 732 compileConstructor(classGen, _lastOutputElement); 733 734 if (!getParser().errorsFound()) { 735 getXSLTC().dumpClass(classGen.getJavaClass()); 736 } 737 } 738 739 745 private void compileStaticInitializer(ClassGenerator classGen) { 746 final ConstantPoolGen cpg = classGen.getConstantPool(); 747 final InstructionList il = new InstructionList(); 748 749 final MethodGenerator staticConst = 750 new MethodGenerator(ACC_PUBLIC|ACC_STATIC, 751 com.sun.org.apache.bcel.internal.generic.Type.VOID, 752 null, null, "<clinit>", 753 _className, il, cpg); 754 755 addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); 756 addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); 757 addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); 758 addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); 759 final int charDataFieldCount = getXSLTC().getCharacterDataCount(); 762 for (int i = 0; i < charDataFieldCount; i++) { 763 addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, 764 STATIC_CHAR_DATA_FIELD+i); 765 } 766 767 final Vector namesIndex = getXSLTC().getNamesIndex(); 769 int size = namesIndex.size(); 770 String [] namesArray = new String [size]; 771 String [] urisArray = new String [size]; 772 int[] typesArray = new int[size]; 773 774 int index; 775 for (int i = 0; i < size; i++) { 776 String encodedName = (String )namesIndex.elementAt(i); 777 if ((index = encodedName.lastIndexOf(':')) > -1) { 778 urisArray[i] = encodedName.substring(0, index); 779 } 780 781 index = index + 1; 782 if (encodedName.charAt(index) == '@') { 783 typesArray[i] = DTM.ATTRIBUTE_NODE; 784 index++; 785 } else if (encodedName.charAt(index) == '?') { 786 typesArray[i] = DTM.NAMESPACE_NODE; 787 index++; 788 } else { 789 typesArray[i] = DTM.ELEMENT_NODE; 790 } 791 792 if (index == 0) { 793 namesArray[i] = encodedName; 794 } 795 else { 796 namesArray[i] = encodedName.substring(index); 797 } 798 } 799 800 il.append(new PUSH(cpg, size)); 801 il.append(new ANEWARRAY(cpg.addClass(STRING))); 802 803 for (int i = 0; i < size; i++) { 804 final String name = namesArray[i]; 805 il.append(DUP); 806 il.append(new PUSH(cpg, i)); 807 il.append(new PUSH(cpg, name)); 808 il.append(AASTORE); 809 } 810 il.append(new PUTSTATIC(cpg.addFieldref(_className, 811 STATIC_NAMES_ARRAY_FIELD, 812 NAMES_INDEX_SIG))); 813 814 il.append(new PUSH(cpg, size)); 815 il.append(new ANEWARRAY(cpg.addClass(STRING))); 816 817 for (int i = 0; i < size; i++) { 818 final String uri = urisArray[i]; 819 il.append(DUP); 820 il.append(new PUSH(cpg, i)); 821 il.append(new PUSH(cpg, uri)); 822 il.append(AASTORE); 823 } 824 il.append(new PUTSTATIC(cpg.addFieldref(_className, 825 STATIC_URIS_ARRAY_FIELD, 826 URIS_INDEX_SIG))); 827 828 il.append(new PUSH(cpg, size)); 829 il.append(new NEWARRAY(BasicType.INT)); 830 831 for (int i = 0; i < size; i++) { 832 final int nodeType = typesArray[i]; 833 il.append(DUP); 834 il.append(new PUSH(cpg, i)); 835 il.append(new PUSH(cpg, nodeType)); 836 il.append(IASTORE); 837 } 838 il.append(new PUTSTATIC(cpg.addFieldref(_className, 839 STATIC_TYPES_ARRAY_FIELD, 840 TYPES_INDEX_SIG))); 841 842 final Vector namespaces = getXSLTC().getNamespaceIndex(); 844 il.append(new PUSH(cpg, namespaces.size())); 845 il.append(new ANEWARRAY(cpg.addClass(STRING))); 846 847 for (int i = 0; i < namespaces.size(); i++) { 848 final String ns = (String )namespaces.elementAt(i); 849 il.append(DUP); 850 il.append(new PUSH(cpg, i)); 851 il.append(new PUSH(cpg, ns)); 852 il.append(AASTORE); 853 } 854 il.append(new PUTSTATIC(cpg.addFieldref(_className, 855 STATIC_NAMESPACE_ARRAY_FIELD, 856 NAMESPACE_INDEX_SIG))); 857 858 final int charDataCount = getXSLTC().getCharacterDataCount(); 860 final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); 861 for (int i = 0; i < charDataCount; i++) { 862 il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); 863 il.append(new INVOKEVIRTUAL(toCharArray)); 864 il.append(new PUTSTATIC(cpg.addFieldref(_className, 865 STATIC_CHAR_DATA_FIELD+i, 866 STATIC_CHAR_DATA_FIELD_SIG))); 867 } 868 869 il.append(RETURN); 870 871 staticConst.stripAttributes(true); 872 staticConst.setMaxLocals(); 873 staticConst.setMaxStack(); 874 classGen.addMethod(staticConst.getMethod()); 875 876 } 877 878 881 private void compileConstructor(ClassGenerator classGen, Output output) { 882 883 final ConstantPoolGen cpg = classGen.getConstantPool(); 884 final InstructionList il = new InstructionList(); 885 886 final MethodGenerator constructor = 887 new MethodGenerator(ACC_PUBLIC, 888 com.sun.org.apache.bcel.internal.generic.Type.VOID, 889 null, null, "<init>", 890 _className, il, cpg); 891 892 il.append(classGen.loadTranslet()); 894 il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, 895 "<init>", "()V"))); 896 897 il.append(classGen.loadTranslet()); 898 il.append(new GETSTATIC(cpg.addFieldref(_className, 899 STATIC_NAMES_ARRAY_FIELD, 900 NAMES_INDEX_SIG))); 901 il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, 902 NAMES_INDEX, 903 NAMES_INDEX_SIG))); 904 905 il.append(classGen.loadTranslet()); 906 il.append(new GETSTATIC(cpg.addFieldref(_className, 907 STATIC_URIS_ARRAY_FIELD, 908 URIS_INDEX_SIG))); 909 il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, 910 URIS_INDEX, 911 URIS_INDEX_SIG))); 912 913 il.append(classGen.loadTranslet()); 914 il.append(new GETSTATIC(cpg.addFieldref(_className, 915 STATIC_TYPES_ARRAY_FIELD, 916 TYPES_INDEX_SIG))); 917 il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, 918 TYPES_INDEX, 919 TYPES_INDEX_SIG))); 920 921 il.append(classGen.loadTranslet()); 922 il.append(new GETSTATIC(cpg.addFieldref(_className, 923 STATIC_NAMESPACE_ARRAY_FIELD, 924 NAMESPACE_INDEX_SIG))); 925 il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, 926 NAMESPACE_INDEX, 927 NAMESPACE_INDEX_SIG))); 928 929 il.append(classGen.loadTranslet()); 930 il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); 931 il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, 932 TRANSLET_VERSION_INDEX, 933 TRANSLET_VERSION_INDEX_SIG))); 934 935 if (_hasIdCall) { 936 il.append(classGen.loadTranslet()); 937 il.append(new PUSH(cpg, Boolean.TRUE)); 938 il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, 939 HASIDCALL_INDEX, 940 HASIDCALL_INDEX_SIG))); 941 } 942 943 if (output != null) { 945 output.translate(classGen, constructor); 947 } 948 949 if (_numberFormattingUsed) 952 DecimalFormatting.translateDefaultDFS(classGen, constructor); 953 954 il.append(RETURN); 955 956 constructor.stripAttributes(true); 957 constructor.setMaxLocals(); 958 constructor.setMaxStack(); 959 classGen.addMethod(constructor.getMethod()); 960 } 961 962 974 private String compileTopLevel(ClassGenerator classGen) { 975 976 final ConstantPoolGen cpg = classGen.getConstantPool(); 977 978 final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = { 979 Util.getJCRefType(DOM_INTF_SIG), 980 Util.getJCRefType(NODE_ITERATOR_SIG), 981 Util.getJCRefType(TRANSLET_OUTPUT_SIG) 982 }; 983 984 final String [] argNames = { 985 DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME 986 }; 987 988 final InstructionList il = new InstructionList(); 989 990 final MethodGenerator toplevel = 991 new MethodGenerator(ACC_PUBLIC, 992 com.sun.org.apache.bcel.internal.generic.Type.VOID, 993 argTypes, argNames, 994 "topLevel", _className, il, 995 classGen.getConstantPool()); 996 997 toplevel.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); 998 999 final LocalVariableGen current = 1001 toplevel.addLocalVariable("current", 1002 com.sun.org.apache.bcel.internal.generic.Type.INT, 1003 il.getEnd(), null); 1004 1005 final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, 1006 "setFilter", 1007 "(Lcom/sun/org/apache/xalan/internal/xsltc/StripFilter;)V"); 1008 1009 il.append(new PUSH(cpg, DTM.ROOT_NODE)); 1010 il.append(new ISTORE(current.getIndex())); 1011 1012 Vector varDepElements = new Vector (_globals); 1014 Enumeration elements = elements(); 1015 while (elements.hasMoreElements()) { 1016 final Object element = elements.nextElement(); 1017 if (element instanceof Key) { 1018 varDepElements.add(element); 1019 } 1020 } 1021 varDepElements = resolveDependencies(varDepElements); 1023 1024 final int count = varDepElements.size(); 1026 1027 for (int i = 0; i < count; i++) { 1028 final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i); 1029 tle.translate(classGen, toplevel); 1030 if (tle instanceof Key) { 1031 final Key key = (Key) tle; 1032 _keys.put(key.getName(), key); 1033 } 1034 } 1035 1036 Vector whitespaceRules = new Vector (); 1038 elements = elements(); 1039 while (elements.hasMoreElements()) { 1040 final Object element = elements.nextElement(); 1041 if (element instanceof DecimalFormatting) { 1043 ((DecimalFormatting)element).translate(classGen,toplevel); 1044 } 1045 else if (element instanceof Whitespace) { 1047 whitespaceRules.addAll(((Whitespace)element).getRules()); 1048 } 1049 } 1050 1051 if (whitespaceRules.size() > 0) { 1053 Whitespace.translateRules(whitespaceRules,classGen); 1054 } 1055 1056 if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { 1057 il.append(toplevel.loadDOM()); 1058 il.append(classGen.loadTranslet()); 1059 il.append(new INVOKEINTERFACE(setFilter, 2)); 1060 } 1061 1062 il.append(RETURN); 1063 1064 toplevel.stripAttributes(true); 1066 toplevel.setMaxLocals(); 1067 toplevel.setMaxStack(); 1068 toplevel.removeNOPs(); 1069 1070 classGen.addMethod(toplevel.getMethod()); 1071 1072 return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); 1073 } 1074 1075 1083 private Vector resolveDependencies(Vector input) { 1084 1085 1096 1097 Vector result = new Vector (); 1098 while (input.size() > 0) { 1099 boolean changed = false; 1100 for (int i = 0; i < input.size(); ) { 1101 final TopLevelElement vde = (TopLevelElement) input.elementAt(i); 1102 final Vector dep = vde.getDependencies(); 1103 if (dep == null || result.containsAll(dep)) { 1104 result.addElement(vde); 1105 input.remove(i); 1106 changed = true; 1107 } 1108 else { 1109 i++; 1110 } 1111 } 1112 1113 if (!changed) { 1115 ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, 1116 input.toString(), this); 1117 getParser().reportError(Constants.ERROR, err); 1118 return(result); 1119 } 1120 } 1121 1122 1129 1130 return result; 1131 } 1132 1133 1139 private String compileBuildKeys(ClassGenerator classGen) { 1140 1141 final ConstantPoolGen cpg = classGen.getConstantPool(); 1142 1143 final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = { 1144 Util.getJCRefType(DOM_INTF_SIG), 1145 Util.getJCRefType(NODE_ITERATOR_SIG), 1146 Util.getJCRefType(TRANSLET_OUTPUT_SIG), 1147 com.sun.org.apache.bcel.internal.generic.Type.INT 1148 }; 1149 1150 final String [] argNames = { 1151 DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME, "current" 1152 }; 1153 1154 final InstructionList il = new InstructionList(); 1155 1156 final MethodGenerator buildKeys = 1157 new MethodGenerator(ACC_PUBLIC, 1158 com.sun.org.apache.bcel.internal.generic.Type.VOID, 1159 argTypes, argNames, 1160 "buildKeys", _className, il, 1161 classGen.getConstantPool()); 1162 1163 buildKeys.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); 1164 1165 final Enumeration elements = elements(); 1166 while (elements.hasMoreElements()) { 1167 final Object element = elements.nextElement(); 1169 if (element instanceof Key) { 1170 final Key key = (Key)element; 1171 key.translate(classGen, buildKeys); 1172 _keys.put(key.getName(),key); 1173 } 1174 } 1175 1176 il.append(RETURN); 1177 1178 buildKeys.stripAttributes(true); 1180 buildKeys.setMaxLocals(); 1181 buildKeys.setMaxStack(); 1182 buildKeys.removeNOPs(); 1183 1184 classGen.addMethod(buildKeys.getMethod()); 1185 1186 return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V"); 1187 } 1188 1189 1194 private void compileTransform(ClassGenerator classGen) { 1195 final ConstantPoolGen cpg = classGen.getConstantPool(); 1196 1197 1201 final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = 1202 new com.sun.org.apache.bcel.internal.generic.Type[3]; 1203 argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); 1204 argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG); 1205 argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG); 1206 1207 final String [] argNames = new String [3]; 1208 argNames[0] = DOCUMENT_PNAME; 1209 argNames[1] = ITERATOR_PNAME; 1210 argNames[2] = TRANSLET_OUTPUT_PNAME; 1211 1212 final InstructionList il = new InstructionList(); 1213 final MethodGenerator transf = 1214 new MethodGenerator(ACC_PUBLIC, 1215 com.sun.org.apache.bcel.internal.generic.Type.VOID, 1216 argTypes, argNames, 1217 "transform", 1218 _className, 1219 il, 1220 classGen.getConstantPool()); 1221 transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); 1222 1223 final LocalVariableGen current = 1225 transf.addLocalVariable("current", 1226 com.sun.org.apache.bcel.internal.generic.Type.INT, 1227 il.getEnd(), null); 1228 final String applyTemplatesSig = classGen.getApplyTemplatesSig(); 1229 final int applyTemplates = cpg.addMethodref(getClassName(), 1230 "applyTemplates", 1231 applyTemplatesSig); 1232 final int domField = cpg.addFieldref(getClassName(), 1233 DOM_FIELD, 1234 DOM_INTF_SIG); 1235 1236 il.append(classGen.loadTranslet()); 1238 1240 if (isMultiDocument()) { 1241 il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS))); 1242 il.append(DUP); 1243 } 1244 1245 il.append(classGen.loadTranslet()); 1246 il.append(transf.loadDOM()); 1247 il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, 1248 "makeDOMAdapter", 1249 "("+DOM_INTF_SIG+")"+ 1250 DOM_ADAPTER_SIG))); 1251 1253 if (isMultiDocument()) { 1254 final int init = cpg.addMethodref(MULTI_DOM_CLASS, 1255 "<init>", 1256 "("+DOM_INTF_SIG+")V"); 1257 il.append(new INVOKESPECIAL(init)); 1258 } 1260 1261 il.append(new PUTFIELD(domField)); 1263 1264 il.append(new PUSH(cpg, DTM.ROOT_NODE)); 1266 il.append(new ISTORE(current.getIndex())); 1267 1268 il.append(classGen.loadTranslet()); 1270 il.append(transf.loadHandler()); 1271 final int index = cpg.addMethodref(TRANSLET_CLASS, 1272 "transferOutputSettings", 1273 "("+OUTPUT_HANDLER_SIG+")V"); 1274 il.append(new INVOKEVIRTUAL(index)); 1275 1276 1282 final String keySig = compileBuildKeys(classGen); 1283 final int keyIdx = cpg.addMethodref(getClassName(), 1284 "buildKeys", keySig); 1285 1286 final Enumeration toplevel = elements(); 1288 if (_globals.size() > 0 || toplevel.hasMoreElements()) { 1289 final String topLevelSig = compileTopLevel(classGen); 1291 final int topLevelIdx = cpg.addMethodref(getClassName(), 1293 "topLevel", 1294 topLevelSig); 1295 il.append(classGen.loadTranslet()); il.append(classGen.loadTranslet()); 1298 il.append(new GETFIELD(domField)); il.append(transf.loadIterator()); 1300 il.append(transf.loadHandler()); il.append(new INVOKEVIRTUAL(topLevelIdx)); 1302 } 1303 1304 1305 1306 1307 il.append(transf.loadHandler()); 1309 il.append(transf.startDocument()); 1310 1311 il.append(classGen.loadTranslet()); 1313 il.append(classGen.loadTranslet()); 1315 il.append(new GETFIELD(domField)); 1316 il.append(transf.loadIterator()); 1318 il.append(transf.loadHandler()); 1319 il.append(new INVOKEVIRTUAL(applyTemplates)); 1320 il.append(transf.loadHandler()); 1322 il.append(transf.endDocument()); 1323 1324 il.append(RETURN); 1325 1326 transf.stripAttributes(true); 1328 transf.setMaxLocals(); 1329 transf.setMaxStack(); 1330 transf.removeNOPs(); 1331 1332 classGen.addMethod(transf.getMethod()); 1333 } 1334 1335 1338 private void peepHoleOptimization(MethodGenerator methodGen) { 1339 final String pattern = "`aload'`pop'`instruction'"; 1340 final InstructionList il = methodGen.getInstructionList(); 1341 final InstructionFinder find = new InstructionFinder(il); 1342 for(Iterator iter=find.search(pattern); iter.hasNext(); ) { 1343 InstructionHandle[] match = (InstructionHandle[])iter.next(); 1344 try { 1345 il.delete(match[0], match[1]); 1346 } 1347 catch (TargetLostException e) { 1348 } 1350 } 1351 } 1352 1353 public int addParam(Param param) { 1354 _globals.addElement(param); 1355 return _globals.size() - 1; 1356 } 1357 1358 public int addVariable(Variable global) { 1359 _globals.addElement(global); 1360 return _globals.size() - 1; 1361 } 1362 1363 public void display(int indent) { 1364 indent(indent); 1365 Util.println("Stylesheet"); 1366 displayContents(indent + IndentIncrement); 1367 } 1368 1369 public String getNamespace(String prefix) { 1371 return lookupNamespace(prefix); 1372 } 1373 1374 public String getClassName() { 1375 return _className; 1376 } 1377 1378 public Vector getTemplates() { 1379 return _templates; 1380 } 1381 1382 public Vector getAllValidTemplates() { 1383 if (_includedStylesheets == null) { 1385 return _templates; 1386 } 1387 1388 if (_allValidTemplates == null) { 1390 Vector templates = new Vector (); 1391 templates.addAll(templates); 1392 int size = _includedStylesheets.size(); 1393 for (int i = 0; i < size; i++) { 1394 Stylesheet included =(Stylesheet)_includedStylesheets.elementAt(i); 1395 templates.addAll(included.getAllValidTemplates()); 1396 } 1397 1399 if (_parentStylesheet != null) { 1401 return templates; 1402 } 1403 _allValidTemplates = templates; 1404 } 1405 1406 return _allValidTemplates; 1407 } 1408 1409 protected void addTemplate(Template template) { 1410 _templates.addElement(template); 1411 } 1412} 1413 | Popular Tags |