1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.io.BufferedOutputStream ; 23 import java.io.ByteArrayOutputStream ; 24 import java.io.File ; 25 import java.io.FileOutputStream ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.net.URL ; 29 import java.util.Date ; 30 import java.util.Enumeration ; 31 import java.util.Hashtable ; 32 import java.util.Map ; 33 import java.util.Properties ; 34 import java.util.Vector ; 35 import java.util.jar.JarEntry ; 36 import java.util.jar.JarOutputStream ; 37 import java.util.jar.Manifest ; 38 39 import org.apache.bcel.classfile.JavaClass; 40 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 41 import org.apache.xalan.xsltc.compiler.util.Util; 42 import org.apache.xml.dtm.DTM; 43 44 import org.xml.sax.InputSource ; 45 import org.xml.sax.XMLReader ; 46 47 54 public final class XSLTC { 55 56 private Parser _parser; 58 59 private XMLReader _reader = null; 61 62 private SourceLoader _loader = null; 64 65 private Stylesheet _stylesheet; 67 68 private int _modeSerial = 1; 71 private int _stylesheetSerial = 1; 72 private int _stepPatternSerial = 1; 73 private int _helperClassSerial = 0; 74 private int _attributeSetSerial = 0; 75 76 private int[] _numberFieldIndexes; 77 78 private int _nextGType; private Vector _namesIndex; private Hashtable _elements; private Hashtable _attributes; 84 private int _nextNSType; private Vector _namespaceIndex; private Hashtable _namespaces; private Hashtable _namespacePrefixes; 90 91 private Vector m_characterData; 93 94 public static final int FILE_OUTPUT = 0; 96 public static final int JAR_OUTPUT = 1; 97 public static final int BYTEARRAY_OUTPUT = 2; 98 public static final int CLASSLOADER_OUTPUT = 3; 99 public static final int BYTEARRAY_AND_FILE_OUTPUT = 4; 100 public static final int BYTEARRAY_AND_JAR_OUTPUT = 5; 101 102 103 private boolean _debug = false; private String _jarFileName = null; private String _className = null; private String _packageName = null; private File _destDir = null; private int _outputType = FILE_OUTPUT; 111 private Vector _classes; 112 private Vector _bcelClasses; 113 private boolean _callsNodeset = false; 114 private boolean _multiDocument = false; 115 private boolean _hasIdCall = false; 116 117 123 private boolean _templateInlining = false; 124 125 128 public XSLTC() { 129 _parser = new Parser(this); 130 } 131 132 135 public Parser getParser() { 136 return _parser; 137 } 138 139 142 public void setOutputType(int type) { 143 _outputType = type; 144 } 145 146 149 public Properties getOutputProperties() { 150 return _parser.getOutputProperties(); 151 } 152 153 156 public void init() { 157 reset(); 158 _reader = null; 159 _classes = new Vector (); 160 _bcelClasses = new Vector (); 161 } 162 163 166 private void reset() { 167 _nextGType = DTM.NTYPES; 168 _elements = new Hashtable (); 169 _attributes = new Hashtable (); 170 _namespaces = new Hashtable (); 171 _namespaces.put("",new Integer (_nextNSType)); 172 _namesIndex = new Vector (128); 173 _namespaceIndex = new Vector (32); 174 _namespacePrefixes = new Hashtable (); 175 _stylesheet = null; 176 _parser.init(); 177 _modeSerial = 1; 179 _stylesheetSerial = 1; 180 _stepPatternSerial = 1; 181 _helperClassSerial = 0; 182 _attributeSetSerial = 0; 183 _multiDocument = false; 184 _hasIdCall = false; 185 _numberFieldIndexes = new int[] { 186 -1, -1, -1 }; 190 } 191 192 197 public void setSourceLoader(SourceLoader loader) { 198 _loader = loader; 199 } 200 201 207 public void setTemplateInlining(boolean templateInlining) { 208 _templateInlining = templateInlining; 209 } 210 211 220 public void setPIParameters(String media, String title, String charset) { 221 _parser.setPIParameters(media, title, charset); 222 } 223 224 228 public boolean compile(URL url) { 229 try { 230 final InputStream stream = url.openStream(); 232 final InputSource input = new InputSource (stream); 233 input.setSystemId(url.toString()); 234 return compile(input, _className); 235 } 236 catch (IOException e) { 237 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 238 return false; 239 } 240 } 241 242 247 public boolean compile(URL url, String name) { 248 try { 249 final InputStream stream = url.openStream(); 251 final InputSource input = new InputSource (stream); 252 input.setSystemId(url.toString()); 253 return compile(input, name); 254 } 255 catch (IOException e) { 256 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 257 return false; 258 } 259 } 260 261 267 public boolean compile(InputStream stream, String name) { 268 final InputSource input = new InputSource (stream); 269 input.setSystemId(name); return compile(input, name); 271 } 272 273 279 public boolean compile(InputSource input, String name) { 280 try { 281 reset(); 283 284 String systemId = null; 286 if (input != null) { 287 systemId = input.getSystemId(); 288 } 289 290 if (_className == null) { 292 if (name != null) { 293 setClassName(name); 294 } 295 else if (systemId != null && !systemId.equals("")) { 296 setClassName(Util.baseName(systemId)); 297 } 298 299 if (_className == null || _className.length() == 0) { 301 setClassName("GregorSamsa"); } 303 } 304 305 SyntaxTreeNode element = null; 307 if (_reader == null) { 308 element = _parser.parse(input); 309 } 310 else { 311 element = _parser.parse(_reader, input); 312 } 313 314 if ((!_parser.errorsFound()) && (element != null)) { 316 _stylesheet = _parser.makeStylesheet(element); 318 _stylesheet.setSourceLoader(_loader); 319 _stylesheet.setSystemId(systemId); 320 _stylesheet.setParentStylesheet(null); 321 _stylesheet.setTemplateInlining(_templateInlining); 322 _parser.setCurrentStylesheet(_stylesheet); 323 324 _parser.createAST(_stylesheet); 326 } 327 if ((!_parser.errorsFound()) && (_stylesheet != null)) { 329 _stylesheet.setCallsNodeset(_callsNodeset); 330 _stylesheet.setMultiDocument(_multiDocument); 331 _stylesheet.setHasIdCall(_hasIdCall); 332 333 synchronized (getClass()) { 335 _stylesheet.translate(); 336 } 337 } 338 } 339 catch (Exception e) { 340 e.printStackTrace(); 341 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 342 } 343 catch (Error e) { 344 if (_debug) e.printStackTrace(); 345 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 346 } 347 finally { 348 _reader = null; } 350 return !_parser.errorsFound(); 351 } 352 353 358 public boolean compile(Vector stylesheets) { 359 final int count = stylesheets.size(); 361 362 if (count == 0) return true; 364 365 if (count == 1) { 368 final Object url = stylesheets.firstElement(); 369 if (url instanceof URL ) 370 return compile((URL )url); 371 else 372 return false; 373 } 374 else { 375 final Enumeration urls = stylesheets.elements(); 377 while (urls.hasMoreElements()) { 378 _className = null; final Object url = urls.nextElement(); 380 if (url instanceof URL ) { 381 if (!compile((URL )url)) return false; 382 } 383 } 384 } 385 return true; 386 } 387 388 392 public byte[][] getBytecodes() { 393 final int count = _classes.size(); 394 final byte[][] result = new byte[count][1]; 395 for (int i = 0; i < count; i++) 396 result[i] = (byte[])_classes.elementAt(i); 397 return result; 398 } 399 400 408 public byte[][] compile(String name, InputSource input, int outputType) { 409 _outputType = outputType; 410 if (compile(input, name)) 411 return getBytecodes(); 412 else 413 return null; 414 } 415 416 423 public byte[][] compile(String name, InputSource input) { 424 return compile(name, input, BYTEARRAY_OUTPUT); 425 } 426 427 431 public void setXMLReader(XMLReader reader) { 432 _reader = reader; 433 } 434 435 438 public XMLReader getXMLReader() { 439 return _reader ; 440 } 441 442 446 public Vector getErrors() { 447 return _parser.getErrors(); 448 } 449 450 454 public Vector getWarnings() { 455 return _parser.getWarnings(); 456 } 457 458 461 public void printErrors() { 462 _parser.printErrors(); 463 } 464 465 468 public void printWarnings() { 469 _parser.printWarnings(); 470 } 471 472 476 protected void setMultiDocument(boolean flag) { 477 _multiDocument = flag; 478 } 479 480 public boolean isMultiDocument() { 481 return _multiDocument; 482 } 483 484 488 protected void setCallsNodeset(boolean flag) { 489 if (flag) setMultiDocument(flag); 490 _callsNodeset = flag; 491 } 492 493 public boolean callsNodeset() { 494 return _callsNodeset; 495 } 496 497 protected void setHasIdCall(boolean flag) { 498 _hasIdCall = flag; 499 } 500 501 public boolean hasIdCall() { 502 return _hasIdCall; 503 } 504 505 511 public void setClassName(String className) { 512 final String base = Util.baseName(className); 513 final String noext = Util.noExtName(base); 514 String name = Util.toJavaName(noext); 515 516 if (_packageName == null) 517 _className = name; 518 else 519 _className = _packageName + '.' + name; 520 } 521 522 525 public String getClassName() { 526 return _className; 527 } 528 529 533 private String classFileName(final String className) { 534 return className.replace('.', File.separatorChar) + ".class"; 535 } 536 537 540 private File getOutputFile(String className) { 541 if (_destDir != null) 542 return new File (_destDir, classFileName(className)); 543 else 544 return new File (classFileName(className)); 545 } 546 547 551 public boolean setDestDirectory(String dstDirName) { 552 final File dir = new File (dstDirName); 553 if (dir.exists() || dir.mkdirs()) { 554 _destDir = dir; 555 return true; 556 } 557 else { 558 _destDir = null; 559 return false; 560 } 561 } 562 563 566 public void setPackageName(String packageName) { 567 _packageName = packageName; 568 if (_className != null) setClassName(_className); 569 } 570 571 575 public void setJarFileName(String jarFileName) { 576 final String JAR_EXT = ".jar"; 577 if (jarFileName.endsWith(JAR_EXT)) 578 _jarFileName = jarFileName; 579 else 580 _jarFileName = jarFileName + JAR_EXT; 581 _outputType = JAR_OUTPUT; 582 } 583 584 public String getJarFileName() { 585 return _jarFileName; 586 } 587 588 591 public void setStylesheet(Stylesheet stylesheet) { 592 if (_stylesheet == null) _stylesheet = stylesheet; 593 } 594 595 598 public Stylesheet getStylesheet() { 599 return _stylesheet; 600 } 601 602 606 public int registerAttribute(QName name) { 607 Integer code = (Integer )_attributes.get(name.toString()); 608 if (code == null) { 609 code = new Integer (_nextGType++); 610 _attributes.put(name.toString(), code); 611 final String uri = name.getNamespace(); 612 final String local = "@"+name.getLocalPart(); 613 if ((uri != null) && (!uri.equals(""))) 614 _namesIndex.addElement(uri+":"+local); 615 else 616 _namesIndex.addElement(local); 617 if (name.getLocalPart().equals("*")) { 618 registerNamespace(name.getNamespace()); 619 } 620 } 621 return code.intValue(); 622 } 623 624 628 public int registerElement(QName name) { 629 Integer code = (Integer )_elements.get(name.toString()); 631 if (code == null) { 632 _elements.put(name.toString(), code = new Integer (_nextGType++)); 633 _namesIndex.addElement(name.toString()); 634 } 635 if (name.getLocalPart().equals("*")) { 636 registerNamespace(name.getNamespace()); 637 } 638 return code.intValue(); 639 } 640 641 645 646 public int registerNamespacePrefix(QName name) { 647 648 Integer code = (Integer )_namespacePrefixes.get(name.toString()); 649 if (code == null) { 650 code = new Integer (_nextGType++); 651 _namespacePrefixes.put(name.toString(), code); 652 final String uri = name.getNamespace(); 653 if ((uri != null) && (!uri.equals(""))){ 654 _namesIndex.addElement("?"); 656 } else{ 657 _namesIndex.addElement("?"+name.getLocalPart()); 658 } 659 } 660 return code.intValue(); 661 } 662 663 667 public int registerNamespace(String namespaceURI) { 668 Integer code = (Integer )_namespaces.get(namespaceURI); 669 if (code == null) { 670 code = new Integer (_nextNSType++); 671 _namespaces.put(namespaceURI,code); 672 _namespaceIndex.addElement(namespaceURI); 673 } 674 return code.intValue(); 675 } 676 677 public int nextModeSerial() { 678 return _modeSerial++; 679 } 680 681 public int nextStylesheetSerial() { 682 return _stylesheetSerial++; 683 } 684 685 public int nextStepPatternSerial() { 686 return _stepPatternSerial++; 687 } 688 689 public int[] getNumberFieldIndexes() { 690 return _numberFieldIndexes; 691 } 692 693 public int nextHelperClassSerial() { 694 return _helperClassSerial++; 695 } 696 697 public int nextAttributeSetSerial() { 698 return _attributeSetSerial++; 699 } 700 701 public Vector getNamesIndex() { 702 return _namesIndex; 703 } 704 705 public Vector getNamespaceIndex() { 706 return _namespaceIndex; 707 } 708 709 713 public String getHelperClassName() { 714 return getClassName() + '$' + _helperClassSerial++; 715 } 716 717 public void dumpClass(JavaClass clazz) { 718 719 if (_outputType == FILE_OUTPUT || 720 _outputType == BYTEARRAY_AND_FILE_OUTPUT) 721 { 722 File outFile = getOutputFile(clazz.getClassName()); 723 String parentDir = outFile.getParent(); 724 if (parentDir != null) { 725 File parentFile = new File (parentDir); 726 if (!parentFile.exists()) 727 parentFile.mkdirs(); 728 } 729 } 730 731 try { 732 switch (_outputType) { 733 case FILE_OUTPUT: 734 clazz.dump( 735 new BufferedOutputStream ( 736 new FileOutputStream ( 737 getOutputFile(clazz.getClassName())))); 738 break; 739 case JAR_OUTPUT: 740 _bcelClasses.addElement(clazz); 741 break; 742 case BYTEARRAY_OUTPUT: 743 case BYTEARRAY_AND_FILE_OUTPUT: 744 case BYTEARRAY_AND_JAR_OUTPUT: 745 case CLASSLOADER_OUTPUT: 746 ByteArrayOutputStream out = new ByteArrayOutputStream (2048); 747 clazz.dump(out); 748 _classes.addElement(out.toByteArray()); 749 750 if (_outputType == BYTEARRAY_AND_FILE_OUTPUT) 751 clazz.dump(new BufferedOutputStream ( 752 new FileOutputStream (getOutputFile(clazz.getClassName())))); 753 else if (_outputType == BYTEARRAY_AND_JAR_OUTPUT) 754 _bcelClasses.addElement(clazz); 755 756 break; 757 } 758 } 759 catch (Exception e) { 760 e.printStackTrace(); 761 } 762 } 763 764 767 private String entryName(File f) throws IOException { 768 return f.getName().replace(File.separatorChar, '/'); 769 } 770 771 774 public void outputToJar() throws IOException { 775 final Manifest manifest = new Manifest (); 777 final java.util.jar.Attributes atrs = manifest.getMainAttributes(); 778 atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.2"); 779 780 final Map map = manifest.getEntries(); 781 Enumeration classes = _bcelClasses.elements(); 783 final String now = (new Date ()).toString(); 784 final java.util.jar.Attributes.Name dateAttr = 785 new java.util.jar.Attributes.Name("Date"); 786 while (classes.hasMoreElements()) { 787 final JavaClass clazz = (JavaClass)classes.nextElement(); 788 final String className = clazz.getClassName().replace('.','/'); 789 final java.util.jar.Attributes attr = new java.util.jar.Attributes (); 790 attr.put(dateAttr, now); 791 map.put(className+".class", attr); 792 } 793 794 final File jarFile = new File (_destDir, _jarFileName); 795 final JarOutputStream jos = 796 new JarOutputStream (new FileOutputStream (jarFile), manifest); 797 classes = _bcelClasses.elements(); 798 while (classes.hasMoreElements()) { 799 final JavaClass clazz = (JavaClass)classes.nextElement(); 800 final String className = clazz.getClassName().replace('.','/'); 801 jos.putNextEntry(new JarEntry (className+".class")); 802 final ByteArrayOutputStream out = new ByteArrayOutputStream (2048); 803 clazz.dump(out); out.writeTo(jos); 805 } 806 jos.close(); 807 } 808 809 812 public void setDebug(boolean debug) { 813 _debug = debug; 814 } 815 816 819 public boolean debug() { 820 return _debug; 821 } 822 823 824 832 public String getCharacterData(int index) { 833 return ((StringBuffer ) m_characterData.elementAt(index)).toString(); 834 } 835 836 840 public int getCharacterDataCount() { 841 return (m_characterData != null) ? m_characterData.size() : 0; 842 } 843 844 851 public int addCharacterData(String newData) { 852 StringBuffer currData; 853 if (m_characterData == null) { 854 m_characterData = new Vector (); 855 currData = new StringBuffer (); 856 m_characterData.addElement(currData); 857 } else { 858 currData = (StringBuffer ) m_characterData 859 .elementAt(m_characterData.size()-1); 860 } 861 862 if (newData.length() + currData.length() > 21845) { 867 currData = new StringBuffer (); 868 m_characterData.addElement(currData); 869 } 870 871 int newDataOffset = currData.length(); 872 currData.append(newData); 873 874 return newDataOffset; 875 } 876 } 877 | Popular Tags |