1 16 19 20 package com.sun.org.apache.xalan.internal.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 com.sun.org.apache.bcel.internal.classfile.JavaClass; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 42 import com.sun.org.apache.xml.internal.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 private boolean _isSecureProcessing = false; 129 130 133 public XSLTC() { 134 _parser = new Parser(this); 135 } 136 137 140 public void setSecureProcessing(boolean flag) { 141 _isSecureProcessing = flag; 142 } 143 144 147 public boolean isSecureProcessing() { 148 return _isSecureProcessing; 149 } 150 151 154 public Parser getParser() { 155 return _parser; 156 } 157 158 161 public void setOutputType(int type) { 162 _outputType = type; 163 } 164 165 168 public Properties getOutputProperties() { 169 return _parser.getOutputProperties(); 170 } 171 172 175 public void init() { 176 reset(); 177 _reader = null; 178 _classes = new Vector (); 179 _bcelClasses = new Vector (); 180 } 181 182 185 private void reset() { 186 _nextGType = DTM.NTYPES; 187 _elements = new Hashtable (); 188 _attributes = new Hashtable (); 189 _namespaces = new Hashtable (); 190 _namespaces.put("",new Integer (_nextNSType)); 191 _namesIndex = new Vector (128); 192 _namespaceIndex = new Vector (32); 193 _namespacePrefixes = new Hashtable (); 194 _stylesheet = null; 195 _parser.init(); 196 _modeSerial = 1; 198 _stylesheetSerial = 1; 199 _stepPatternSerial = 1; 200 _helperClassSerial = 0; 201 _attributeSetSerial = 0; 202 _multiDocument = false; 203 _hasIdCall = false; 204 _numberFieldIndexes = new int[] { 205 -1, -1, -1 }; 209 } 210 211 216 public void setSourceLoader(SourceLoader loader) { 217 _loader = loader; 218 } 219 220 226 public void setTemplateInlining(boolean templateInlining) { 227 _templateInlining = templateInlining; 228 } 229 230 239 public void setPIParameters(String media, String title, String charset) { 240 _parser.setPIParameters(media, title, charset); 241 } 242 243 247 public boolean compile(URL url) { 248 try { 249 final InputStream stream = url.openStream(); 251 final InputSource input = new InputSource (stream); 252 input.setSystemId(url.toString()); 253 return compile(input, _className); 254 } 255 catch (IOException e) { 256 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 257 return false; 258 } 259 } 260 261 266 public boolean compile(URL url, String name) { 267 try { 268 final InputStream stream = url.openStream(); 270 final InputSource input = new InputSource (stream); 271 input.setSystemId(url.toString()); 272 return compile(input, name); 273 } 274 catch (IOException e) { 275 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 276 return false; 277 } 278 } 279 280 286 public boolean compile(InputStream stream, String name) { 287 final InputSource input = new InputSource (stream); 288 input.setSystemId(name); return compile(input, name); 290 } 291 292 298 public boolean compile(InputSource input, String name) { 299 try { 300 reset(); 302 303 String systemId = null; 305 if (input != null) { 306 systemId = input.getSystemId(); 307 } 308 309 if (_className == null) { 311 if (name != null) { 312 setClassName(name); 313 } 314 else if (systemId != null && !systemId.equals("")) { 315 setClassName(Util.baseName(systemId)); 316 } 317 318 if (_className == null || _className.length() == 0) { 320 setClassName("GregorSamsa"); } 322 } 323 324 SyntaxTreeNode element = null; 326 if (_reader == null) { 327 element = _parser.parse(input); 328 } 329 else { 330 element = _parser.parse(_reader, input); 331 } 332 333 if ((!_parser.errorsFound()) && (element != null)) { 335 _stylesheet = _parser.makeStylesheet(element); 337 _stylesheet.setSourceLoader(_loader); 338 _stylesheet.setSystemId(systemId); 339 _stylesheet.setParentStylesheet(null); 340 _stylesheet.setTemplateInlining(_templateInlining); 341 _parser.setCurrentStylesheet(_stylesheet); 342 343 _parser.createAST(_stylesheet); 345 } 346 if ((!_parser.errorsFound()) && (_stylesheet != null)) { 348 _stylesheet.setCallsNodeset(_callsNodeset); 349 _stylesheet.setMultiDocument(_multiDocument); 350 _stylesheet.setHasIdCall(_hasIdCall); 351 352 synchronized (getClass()) { 354 _stylesheet.translate(); 355 } 356 } 357 } 358 catch (Exception e) { 359 e.printStackTrace(); 360 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 361 } 362 catch (Error e) { 363 if (_debug) e.printStackTrace(); 364 _parser.reportError(Constants.FATAL, new ErrorMsg(e)); 365 } 366 finally { 367 _reader = null; } 369 return !_parser.errorsFound(); 370 } 371 372 377 public boolean compile(Vector stylesheets) { 378 final int count = stylesheets.size(); 380 381 if (count == 0) return true; 383 384 if (count == 1) { 387 final Object url = stylesheets.firstElement(); 388 if (url instanceof URL ) 389 return compile((URL )url); 390 else 391 return false; 392 } 393 else { 394 final Enumeration urls = stylesheets.elements(); 396 while (urls.hasMoreElements()) { 397 _className = null; final Object url = urls.nextElement(); 399 if (url instanceof URL ) { 400 if (!compile((URL )url)) return false; 401 } 402 } 403 } 404 return true; 405 } 406 407 411 public byte[][] getBytecodes() { 412 final int count = _classes.size(); 413 final byte[][] result = new byte[count][1]; 414 for (int i = 0; i < count; i++) 415 result[i] = (byte[])_classes.elementAt(i); 416 return result; 417 } 418 419 427 public byte[][] compile(String name, InputSource input, int outputType) { 428 _outputType = outputType; 429 if (compile(input, name)) 430 return getBytecodes(); 431 else 432 return null; 433 } 434 435 442 public byte[][] compile(String name, InputSource input) { 443 return compile(name, input, BYTEARRAY_OUTPUT); 444 } 445 446 450 public void setXMLReader(XMLReader reader) { 451 _reader = reader; 452 } 453 454 457 public XMLReader getXMLReader() { 458 return _reader ; 459 } 460 461 465 public Vector getErrors() { 466 return _parser.getErrors(); 467 } 468 469 473 public Vector getWarnings() { 474 return _parser.getWarnings(); 475 } 476 477 480 public void printErrors() { 481 _parser.printErrors(); 482 } 483 484 487 public void printWarnings() { 488 _parser.printWarnings(); 489 } 490 491 495 protected void setMultiDocument(boolean flag) { 496 _multiDocument = flag; 497 } 498 499 public boolean isMultiDocument() { 500 return _multiDocument; 501 } 502 503 507 protected void setCallsNodeset(boolean flag) { 508 if (flag) setMultiDocument(flag); 509 _callsNodeset = flag; 510 } 511 512 public boolean callsNodeset() { 513 return _callsNodeset; 514 } 515 516 protected void setHasIdCall(boolean flag) { 517 _hasIdCall = flag; 518 } 519 520 public boolean hasIdCall() { 521 return _hasIdCall; 522 } 523 524 530 public void setClassName(String className) { 531 final String base = Util.baseName(className); 532 final String noext = Util.noExtName(base); 533 String name = Util.toJavaName(noext); 534 535 if (_packageName == null) 536 _className = name; 537 else 538 _className = _packageName + '.' + name; 539 } 540 541 544 public String getClassName() { 545 return _className; 546 } 547 548 552 private String classFileName(final String className) { 553 return className.replace('.', File.separatorChar) + ".class"; 554 } 555 556 559 private File getOutputFile(String className) { 560 if (_destDir != null) 561 return new File (_destDir, classFileName(className)); 562 else 563 return new File (classFileName(className)); 564 } 565 566 570 public boolean setDestDirectory(String dstDirName) { 571 final File dir = new File (dstDirName); 572 if (dir.exists() || dir.mkdirs()) { 573 _destDir = dir; 574 return true; 575 } 576 else { 577 _destDir = null; 578 return false; 579 } 580 } 581 582 585 public void setPackageName(String packageName) { 586 _packageName = packageName; 587 if (_className != null) setClassName(_className); 588 } 589 590 594 public void setJarFileName(String jarFileName) { 595 final String JAR_EXT = ".jar"; 596 if (jarFileName.endsWith(JAR_EXT)) 597 _jarFileName = jarFileName; 598 else 599 _jarFileName = jarFileName + JAR_EXT; 600 _outputType = JAR_OUTPUT; 601 } 602 603 public String getJarFileName() { 604 return _jarFileName; 605 } 606 607 610 public void setStylesheet(Stylesheet stylesheet) { 611 if (_stylesheet == null) _stylesheet = stylesheet; 612 } 613 614 617 public Stylesheet getStylesheet() { 618 return _stylesheet; 619 } 620 621 625 public int registerAttribute(QName name) { 626 Integer code = (Integer )_attributes.get(name.toString()); 627 if (code == null) { 628 code = new Integer (_nextGType++); 629 _attributes.put(name.toString(), code); 630 final String uri = name.getNamespace(); 631 final String local = "@"+name.getLocalPart(); 632 if ((uri != null) && (!uri.equals(""))) 633 _namesIndex.addElement(uri+":"+local); 634 else 635 _namesIndex.addElement(local); 636 if (name.getLocalPart().equals("*")) { 637 registerNamespace(name.getNamespace()); 638 } 639 } 640 return code.intValue(); 641 } 642 643 647 public int registerElement(QName name) { 648 Integer code = (Integer )_elements.get(name.toString()); 650 if (code == null) { 651 _elements.put(name.toString(), code = new Integer (_nextGType++)); 652 _namesIndex.addElement(name.toString()); 653 } 654 if (name.getLocalPart().equals("*")) { 655 registerNamespace(name.getNamespace()); 656 } 657 return code.intValue(); 658 } 659 660 664 665 public int registerNamespacePrefix(QName name) { 666 667 Integer code = (Integer )_namespacePrefixes.get(name.toString()); 668 if (code == null) { 669 code = new Integer (_nextGType++); 670 _namespacePrefixes.put(name.toString(), code); 671 final String uri = name.getNamespace(); 672 if ((uri != null) && (!uri.equals(""))){ 673 _namesIndex.addElement("?"); 675 } else{ 676 _namesIndex.addElement("?"+name.getLocalPart()); 677 } 678 } 679 return code.intValue(); 680 } 681 682 686 public int registerNamespace(String namespaceURI) { 687 Integer code = (Integer )_namespaces.get(namespaceURI); 688 if (code == null) { 689 code = new Integer (_nextNSType++); 690 _namespaces.put(namespaceURI,code); 691 _namespaceIndex.addElement(namespaceURI); 692 } 693 return code.intValue(); 694 } 695 696 public int nextModeSerial() { 697 return _modeSerial++; 698 } 699 700 public int nextStylesheetSerial() { 701 return _stylesheetSerial++; 702 } 703 704 public int nextStepPatternSerial() { 705 return _stepPatternSerial++; 706 } 707 708 public int[] getNumberFieldIndexes() { 709 return _numberFieldIndexes; 710 } 711 712 public int nextHelperClassSerial() { 713 return _helperClassSerial++; 714 } 715 716 public int nextAttributeSetSerial() { 717 return _attributeSetSerial++; 718 } 719 720 public Vector getNamesIndex() { 721 return _namesIndex; 722 } 723 724 public Vector getNamespaceIndex() { 725 return _namespaceIndex; 726 } 727 728 732 public String getHelperClassName() { 733 return getClassName() + '$' + _helperClassSerial++; 734 } 735 736 public void dumpClass(JavaClass clazz) { 737 738 if (_outputType == FILE_OUTPUT || 739 _outputType == BYTEARRAY_AND_FILE_OUTPUT) 740 { 741 File outFile = getOutputFile(clazz.getClassName()); 742 String parentDir = outFile.getParent(); 743 if (parentDir != null) { 744 File parentFile = new File (parentDir); 745 if (!parentFile.exists()) 746 parentFile.mkdirs(); 747 } 748 } 749 750 try { 751 switch (_outputType) { 752 case FILE_OUTPUT: 753 clazz.dump( 754 new BufferedOutputStream ( 755 new FileOutputStream ( 756 getOutputFile(clazz.getClassName())))); 757 break; 758 case JAR_OUTPUT: 759 _bcelClasses.addElement(clazz); 760 break; 761 case BYTEARRAY_OUTPUT: 762 case BYTEARRAY_AND_FILE_OUTPUT: 763 case BYTEARRAY_AND_JAR_OUTPUT: 764 case CLASSLOADER_OUTPUT: 765 ByteArrayOutputStream out = new ByteArrayOutputStream (2048); 766 clazz.dump(out); 767 _classes.addElement(out.toByteArray()); 768 769 if (_outputType == BYTEARRAY_AND_FILE_OUTPUT) 770 clazz.dump(new BufferedOutputStream ( 771 new FileOutputStream (getOutputFile(clazz.getClassName())))); 772 else if (_outputType == BYTEARRAY_AND_JAR_OUTPUT) 773 _bcelClasses.addElement(clazz); 774 775 break; 776 } 777 } 778 catch (Exception e) { 779 e.printStackTrace(); 780 } 781 } 782 783 786 private String entryName(File f) throws IOException { 787 return f.getName().replace(File.separatorChar, '/'); 788 } 789 790 793 public void outputToJar() throws IOException { 794 final Manifest manifest = new Manifest (); 796 final java.util.jar.Attributes atrs = manifest.getMainAttributes(); 797 atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.2"); 798 799 final Map map = manifest.getEntries(); 800 Enumeration classes = _bcelClasses.elements(); 802 final String now = (new Date ()).toString(); 803 final java.util.jar.Attributes.Name dateAttr = 804 new java.util.jar.Attributes.Name("Date"); 805 while (classes.hasMoreElements()) { 806 final JavaClass clazz = (JavaClass)classes.nextElement(); 807 final String className = clazz.getClassName().replace('.','/'); 808 final java.util.jar.Attributes attr = new java.util.jar.Attributes (); 809 attr.put(dateAttr, now); 810 map.put(className+".class", attr); 811 } 812 813 final File jarFile = new File (_destDir, _jarFileName); 814 final JarOutputStream jos = 815 new JarOutputStream (new FileOutputStream (jarFile), manifest); 816 classes = _bcelClasses.elements(); 817 while (classes.hasMoreElements()) { 818 final JavaClass clazz = (JavaClass)classes.nextElement(); 819 final String className = clazz.getClassName().replace('.','/'); 820 jos.putNextEntry(new JarEntry (className+".class")); 821 final ByteArrayOutputStream out = new ByteArrayOutputStream (2048); 822 clazz.dump(out); out.writeTo(jos); 824 } 825 jos.close(); 826 } 827 828 831 public void setDebug(boolean debug) { 832 _debug = debug; 833 } 834 835 838 public boolean debug() { 839 return _debug; 840 } 841 842 843 851 public String getCharacterData(int index) { 852 return ((StringBuffer ) m_characterData.elementAt(index)).toString(); 853 } 854 855 859 public int getCharacterDataCount() { 860 return (m_characterData != null) ? m_characterData.size() : 0; 861 } 862 863 870 public int addCharacterData(String newData) { 871 StringBuffer currData; 872 if (m_characterData == null) { 873 m_characterData = new Vector (); 874 currData = new StringBuffer (); 875 m_characterData.addElement(currData); 876 } else { 877 currData = (StringBuffer ) m_characterData 878 .elementAt(m_characterData.size()-1); 879 } 880 881 if (newData.length() + currData.length() > 21845) { 886 currData = new StringBuffer (); 887 m_characterData.addElement(currData); 888 } 889 890 int newDataOffset = currData.length(); 891 currData.append(newData); 892 893 return newDataOffset; 894 } 895 } 896 | Popular Tags |