| 1 16 19 package com.sun.org.apache.xml.internal.serializer; 20 21 import java.io.IOException ; 22 import java.io.OutputStream ; 23 import java.io.UnsupportedEncodingException ; 24 import java.io.Writer ; 25 import java.util.Properties ; 26 import java.util.StringTokenizer ; 27 import java.util.Vector ; 28 29 import javax.xml.transform.OutputKeys ; 30 import javax.xml.transform.Transformer ; 31 32 import com.sun.org.apache.xml.internal.res.XMLErrorResources; 33 import com.sun.org.apache.xml.internal.res.XMLMessages; 34 import com.sun.org.apache.xml.internal.utils.BoolStack; 35 import com.sun.org.apache.xml.internal.utils.FastStringBuffer; 36 import com.sun.org.apache.xml.internal.utils.QName; 37 import com.sun.org.apache.xml.internal.utils.TreeWalker; 38 import com.sun.org.apache.xml.internal.utils.WrappedRuntimeException; 39 import org.w3c.dom.Node ; 40 import org.xml.sax.Attributes ; 41 import org.xml.sax.ContentHandler ; 42 import org.xml.sax.SAXException ; 43 44 46 52 abstract public class ToStream extends SerializerBase 53 { 54 55 private static final String COMMENT_BEGIN = "<!--"; 56 private static final String COMMENT_END = "-->"; 57 58 59 protected BoolStack m_disableOutputEscapingStates = new BoolStack(); 60 61 64 boolean m_triedToGetConverter = false; 65 69 java.lang.reflect.Method m_canConvertMeth; 70 71 75 Object m_charToByteConverter = null; 76 77 86 protected BoolStack m_preserves = new BoolStack(); 87 88 96 protected boolean m_ispreserve = false; 97 98 106 protected boolean m_isprevtext = false; 107 108 112 protected int m_maxCharacter = Encodings.getLastPrintable(); 113 114 117 protected final char[] m_lineSep = 118 System.getProperty("line.separator").toCharArray(); 119 120 123 protected boolean m_lineSepUse = true; 124 125 129 protected final int m_lineSepLen = m_lineSep.length; 130 131 135 protected CharInfo m_charInfo; 136 137 138 boolean m_shouldFlush = true; 139 140 143 protected boolean m_spaceBeforeClose = false; 144 145 151 boolean m_startNewLine; 152 153 156 protected boolean m_inDoctype = false; 157 158 161 boolean m_isUTF8 = false; 162 163 164 protected Properties m_format; 165 166 169 protected boolean m_cdataStartCalled = false; 170 171 174 public ToStream() 175 { 176 } 177 178 183 protected void closeCDATA() throws org.xml.sax.SAXException  184 { 185 try 186 { 187 m_writer.write(CDATA_DELIMITER_CLOSE); 188 m_cdataTagOpen = false; } 191 catch (IOException e) 192 { 193 throw new SAXException (e); 194 } 195 } 196 197 206 public void serialize(Node node) throws IOException  207 { 208 209 try 210 { 211 TreeWalker walker = 212 new TreeWalker(this, new com.sun.org.apache.xml.internal.utils.DOM2Helper()); 213 214 walker.traverse(node); 215 } 216 catch (org.xml.sax.SAXException se) 217 { 218 throw new WrappedRuntimeException(se); 219 } 220 } 221 222 229 static final boolean isUTF16Surrogate(char c) 230 { 231 return (c & 0xFC00) == 0xD800; 232 } 233 234 237 private boolean m_escaping = true; 238 239 244 protected final void flushWriter() throws org.xml.sax.SAXException  245 { 246 final java.io.Writer writer = m_writer; 247 if (null != writer) 248 { 249 try 250 { 251 if (writer instanceof WriterToUTF8Buffered) 252 { 253 if (m_shouldFlush) 254 ((WriterToUTF8Buffered) writer).flush(); 255 else 256 ((WriterToUTF8Buffered) writer).flushBuffer(); 257 } 258 if (writer instanceof WriterToASCI) 259 { 260 if (m_shouldFlush) 261 writer.flush(); 262 } 263 else 264 { 265 writer.flush(); 269 } 270 } 271 catch (IOException ioe) 272 { 273 throw new org.xml.sax.SAXException (ioe); 274 } 275 } 276 } 277 278 284 public OutputStream getOutputStream() 285 { 286 287 if (m_writer instanceof WriterToUTF8Buffered) 288 return ((WriterToUTF8Buffered) m_writer).getOutputStream(); 289 if (m_writer instanceof WriterToASCI) 290 return ((WriterToASCI) m_writer).getOutputStream(); 291 else 292 return null; 293 } 294 295 297 310 public void elementDecl(String name, String model) throws SAXException  311 { 312 if (m_inExternalDTD) 314 return; 315 try 316 { 317 final java.io.Writer writer = m_writer; 318 if (m_needToOutputDocTypeDecl) 319 { 320 outputDocTypeDecl(m_elemContext.m_elementName, false); 321 m_needToOutputDocTypeDecl = false; 322 } 323 if (m_inDoctype) 324 { 325 writer.write(" ["); 326 writer.write(m_lineSep, 0, m_lineSepLen); 327 328 m_inDoctype = false; 329 } 330 331 writer.write("<!ELEMENT "); 332 writer.write(name); 333 writer.write(' '); 334 writer.write(model); 335 writer.write('>'); 336 writer.write(m_lineSep, 0, m_lineSepLen); 337 } 338 catch (IOException e) 339 { 340 throw new SAXException (e); 341 } 342 343 } 344 345 358 public void internalEntityDecl(String name, String value) 359 throws SAXException  360 { 361 if (m_inExternalDTD) 363 return; 364 try 365 { 366 if (m_needToOutputDocTypeDecl) 367 { 368 outputDocTypeDecl(m_elemContext.m_elementName, false); 369 m_needToOutputDocTypeDecl = false; 370 } 371 if (m_inDoctype) 372 { 373 final java.io.Writer writer = m_writer; 374 writer.write(" ["); 375 writer.write(m_lineSep, 0, m_lineSepLen); 376 377 m_inDoctype = false; 378 } 379 380 outputEntityDecl(name, value); 381 } 382 catch (IOException e) 383 { 384 throw new SAXException (e); 385 } 386 387 } 388 389 397 void outputEntityDecl(String name, String value) throws IOException  398 { 399 final java.io.Writer writer = m_writer; 400 writer.write("<!ENTITY "); 401 writer.write(name); 402 writer.write(" \""); 403 writer.write(value); 404 writer.write("\">"); 405 writer.write(m_lineSep, 0, m_lineSepLen); 406 } 407 408 413 protected final void outputLineSep() throws IOException  414 { 415 416 m_writer.write(m_lineSep, 0, m_lineSepLen); 417 } 418 419 428 public void setOutputFormat(Properties format) 429 { 430 431 boolean shouldFlush = m_shouldFlush; 432 433 init(m_writer, format, false, false); 434 435 m_shouldFlush = shouldFlush; 436 } 437 438 446 private synchronized void init( 447 Writer writer, 448 Properties format, 449 boolean defaultProperties, 450 boolean shouldFlush) 451 { 452 453 m_shouldFlush = shouldFlush; 454 455 456 if (m_tracer != null 459 && !(writer instanceof SerializerTraceWriter) ) 460 m_writer = new SerializerTraceWriter(writer, m_tracer); 461 else 462 m_writer = writer; 463 464 465 m_format = format; 466 setCdataSectionElements(OutputKeys.CDATA_SECTION_ELEMENTS, format); 471 472 setIndentAmount( 473 OutputPropertyUtils.getIntProperty( 474 OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, 475 format)); 476 setIndent( 477 OutputPropertyUtils.getBooleanProperty(OutputKeys.INDENT, format)); 478 479 boolean shouldNotWriteXMLHeader = 480 OutputPropertyUtils.getBooleanProperty( 481 OutputKeys.OMIT_XML_DECLARATION, 482 format); 483 setOmitXMLDeclaration(shouldNotWriteXMLHeader); 484 setDoctypeSystem(format.getProperty(OutputKeys.DOCTYPE_SYSTEM)); 485 String doctypePublic = format.getProperty(OutputKeys.DOCTYPE_PUBLIC); 486 setDoctypePublic(doctypePublic); 487 488 if (format.get(OutputKeys.STANDALONE) != null) 490 { 491 String val = format.getProperty(OutputKeys.STANDALONE); 492 if (defaultProperties) 493 setStandaloneInternal(val); 494 else 495 setStandalone(val); 496 } 497 498 setMediaType(format.getProperty(OutputKeys.MEDIA_TYPE)); 499 500 if (null != doctypePublic) 501 { 502 if (doctypePublic.startsWith("-//W3C//DTD XHTML")) 503 m_spaceBeforeClose = true; 504 } 505 506 String encoding = getEncoding(); 508 if (null == encoding) 509 { 510 encoding = 511 Encodings.getMimeEncoding( 512 format.getProperty(OutputKeys.ENCODING)); 513 setEncoding(encoding); 514 } 515 516 m_isUTF8 = encoding.equals(Encodings.DEFAULT_MIME_ENCODING); 517 m_maxCharacter = Encodings.getLastPrintable(encoding); 518 519 String entitiesFileName = 522 (String ) format.get(OutputPropertiesFactory.S_KEY_ENTITIES); 523 524 if (null != entitiesFileName) 525 { 526 527 String method = 528 (String ) format.get(OutputKeys.METHOD); 529 530 m_charInfo = CharInfo.getCharInfo(entitiesFileName, method); 531 } 532 533 } 534 535 542 private synchronized void init(Writer writer, Properties format) 543 { 544 init(writer, format, false, false); 545 } 546 558 protected synchronized void init( 559 OutputStream output, 560 Properties format, 561 boolean defaultProperties) 562 throws UnsupportedEncodingException  563 { 564 565 String encoding = getEncoding(); 566 if (encoding == null) 567 { 568 encoding = 570 Encodings.getMimeEncoding( 571 format.getProperty(OutputKeys.ENCODING)); 572 setEncoding(encoding); 573 } 574 575 if (encoding.equalsIgnoreCase("UTF-8")) 576 { 577 m_isUTF8 = true; 578 593 594 init( 595 new WriterToUTF8Buffered(output), 596 format, 597 defaultProperties, 598 true); 599 600 601 } 602 else if ( 603 encoding.equals("WINDOWS-1250") 604 || encoding.equals("US-ASCII") 605 || encoding.equals("ASCII")) 606 { 607 init(new WriterToASCI(output), format, defaultProperties, true); 608 } 609 else 610 { 611 Writer osw; 612 613 try 614 { 615 osw = Encodings.getWriter(output, encoding); 616 } 617 catch (UnsupportedEncodingException uee) 618 { 619 System.out.println( 620 "Warning: encoding \"" 621 + encoding 622 + "\" not supported" 623 + ", using " 624 + Encodings.DEFAULT_MIME_ENCODING); 625 626 encoding = Encodings.DEFAULT_MIME_ENCODING; 627 setEncoding(encoding); 628 osw = Encodings.getWriter(output, encoding); 629 } 630 631 m_maxCharacter = Encodings.getLastPrintable(encoding); 632 633 init(osw, format, defaultProperties, true); 634 } 635 636 } 637 638 643 public Properties getOutputFormat() 644 { 645 return m_format; 646 } 647 648 655 public void setWriter(Writer writer) 656 { 657 if (m_tracer != null 660 && !(writer instanceof SerializerTraceWriter) ) 661 m_writer = new SerializerTraceWriter(writer, m_tracer); 662 else 663 m_writer = writer; 664 } 665 666 678 public boolean setLineSepUse(boolean use_sytem_line_break) 679 { 680 boolean oldValue = m_lineSepUse; 681 m_lineSepUse = use_sytem_line_break; 682 return oldValue; 683 } 684 685 696 public void setOutputStream(OutputStream output) 697 { 698 699 try 700 { 701 Properties format; 702 if (null == m_format) 703 format = 704 OutputPropertiesFactory.getDefaultMethodProperties( 705 Method.XML); 706 else 707 format = m_format; 708 init(output, format, true); 709 } 710 catch (UnsupportedEncodingException uee) 711 { 712 713 } 715 } 716 717 720 public boolean setEscaping(boolean escape) 721 { 722 final boolean temp = m_escaping; 723 m_escaping = escape; 724 return temp; 725 726 } 727 728 729 737 protected void indent(int depth) throws IOException  738 { 739 740 if (m_startNewLine) 741 outputLineSep(); 742 746 if (m_indentAmount > 0) 747 printSpace(depth * m_indentAmount); 748 749 } 750 751 755 protected void indent() throws IOException  756 { 757 indent(m_elemContext.m_currentElemDepth); 758 } 759 766 private void printSpace(int n) throws IOException  767 { 768 final java.io.Writer writer = m_writer; 769 for (int i = 0; i < n; i++) 770 { 771 writer.write(' '); 772 } 773 774 } 775 776 795 public void attributeDecl( 796 String eName, 797 String aName, 798 String type, 799 String valueDefault, 800 String value) 801 throws SAXException  802 { 803 if (m_inExternalDTD) 805 return; 806 try 807 { 808 final java.io.Writer writer = m_writer; 809 if (m_needToOutputDocTypeDecl) 810 { 811 outputDocTypeDecl(m_elemContext.m_elementName, false); 812 m_needToOutputDocTypeDecl = false; 813 } 814 if (m_inDoctype) 815 { 816 writer.write(" ["); 817 writer.write(m_lineSep, 0, m_lineSepLen); 818 819 m_inDoctype = false; 820 } 821 822 writer.write("<!ATTLIST "); 823 writer.write(eName); 824 writer.write(' '); 825 826 writer.write(aName); 827 writer.write(' '); 828 writer.write(type); 829 if (valueDefault != null) 830 { 831 writer.write(' '); 832 writer.write(valueDefault); 833 } 834 835 writer.write('>'); 838 writer.write(m_lineSep, 0, m_lineSepLen); 839 } 840 catch (IOException e) 841 { 842 throw new SAXException (e); 843 } 844 } 845 846 851 public Writer getWriter() 852 { 853 return m_writer; 854 } 855 856 871 public void externalEntityDecl( 872 String name, 873 String publicId, 874 String systemId) 875 throws SAXException  876 { 877 } 878 879 882 protected boolean escapingNotNeeded(char ch) 883 { 884 if (ch < 127) 885 { 886 if (ch >= 0x20 || (0x0A == ch || 0x0D == ch || 0x09 == ch)) 887 return true; 888 else 889 return false; 890 } 891 892 if (null == m_charToByteConverter && false == m_triedToGetConverter) 893 { 894 m_triedToGetConverter = true; 895 try 896 { 897 m_charToByteConverter = 898 Encodings.getCharToByteConverter(getEncoding()); 899 if (null != m_charToByteConverter) 900
|