src/com/sun/org/apache/xml/internal/serializer/SerializerBase.java

Print this page


   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2001-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");


   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: SerializerBase.java,v 1.5 2006/04/14 12:09:19 sunithareddy Exp $
  22  */
  23 package com.sun.org.apache.xml.internal.serializer;
  24 
  25 import java.io.IOException;
  26 import java.util.Vector;


  27 

  28 import javax.xml.transform.SourceLocator;
  29 import javax.xml.transform.Transformer;
  30 
  31 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
  32 import com.sun.org.apache.xml.internal.serializer.utils.Utils;
  33 import org.xml.sax.Attributes;
  34 import org.xml.sax.ContentHandler;
  35 import org.xml.sax.Locator;
  36 import org.xml.sax.SAXException;
  37 import org.xml.sax.SAXParseException;
  38 import org.xml.sax.ext.Locator2;
  39 
  40 
  41 /**
  42  * This class acts as a base class for the XML "serializers"
  43  * and the stream serializers.
  44  * It contains a number of common fields and methods.
  45  *
  46  * @xsl.usage internal
  47  */


  91     protected boolean m_cdataTagOpen = false;
  92 
  93     /**
  94      * All the attributes of the current element, collected from
  95      * startPrefixMapping() calls, or addAddtribute() calls, or
  96      * from the SAX attributes in a startElement() call.
  97      */
  98     protected AttributesImplSerializer m_attributes = new AttributesImplSerializer();
  99 
 100     /**
 101      * Tells if we're in an EntityRef event.
 102      */
 103     protected boolean m_inEntityRef = false;
 104 
 105     /** This flag is set while receiving events from the external DTD */
 106     protected boolean m_inExternalDTD = false;
 107 
 108     /**
 109      * The System ID for the doc type.
 110      */
 111     private String m_doctypeSystem;
 112 
 113     /**
 114      * The public ID for the doc type.
 115      */
 116     private String m_doctypePublic;
 117 
 118     /**
 119      * Flag to tell that we need to add the doctype decl, which we can't do
 120      * until the first element is encountered.
 121      */
 122     boolean m_needToOutputDocTypeDecl = true;
 123 
 124     /**
 125      * The character encoding.  Must match the encoding used for the
 126      * printWriter.
 127      */
 128     private String m_encoding = null;
 129 
 130     /**
 131      * Tells if we should write the XML declaration.
 132      */
 133     private boolean m_shouldNotWriteXMLHeader = false;
 134 
 135     /**
 136      * The standalone value for the doctype.
 137      */
 138     private String m_standalone;
 139 
 140     /**
 141      * True if standalone was specified.
 142      */
 143     protected boolean m_standaloneWasSpecified = false;
 144 
 145     /**
 146      * Determine if the output is a standalone.
 147      */
 148     protected boolean m_isStandalone = false;
 149 
 150     /**
 151      * Flag to tell if indenting (pretty-printing) is on.
 152      */
 153     protected boolean m_doIndent = false;
 154     /**
 155      * Amount to indent.
 156      */
 157     protected int m_indentAmount = 0;
 158 
 159     /**
 160      * Tells the XML version, for writing out to the XML decl.
 161      */
 162     private String m_version = null;
 163 
 164     /**
 165      * The mediatype.  Not used right now.
 166      */
 167     private String m_mediatype;
 168 
 169     /**
 170      * The transformer that was around when this output handler was created (if
 171      * any).
 172      */
 173     private Transformer m_transformer;
 174 
 175     /**
 176      * Pairs of local names and corresponding URIs of CDATA sections. This list
 177      * comes from the cdata-section-elements attribute. Every second one is a
 178      * local name, and every other second one is the URI for the local name.
 179      */
 180     protected Vector m_cdataSectionElements = null;
 181 
 182     /**
 183      * Namespace support, that keeps track of currently defined
 184      * prefix/uri mappings. As processed elements come and go, so do
 185      * the associated mappings for that element.
 186      */
 187     protected NamespaceMappings m_prefixMap;
 188 
 189     /**
 190      * Handle for firing generate events.  This interface may be implemented
 191      * by the referenced transformer object.
 192      */
 193     protected SerializerTrace m_tracer;
 194 
 195     protected SourceLocator m_sourceLocator;
 196 
 197 
 198     /**
 199      * The writer to send output to. This field is only used in the ToStream
 200      * serializers, but exists here just so that the fireStartDoc() and
 201      * other fire... methods can flush this writer when tracing.
 202      */


 521     {
 522         // do nothing (base behavior)
 523     }
 524 
 525     /**
 526      * Initialize global variables
 527      */
 528     protected void initCDATA()
 529     {
 530         // CDATA stack
 531         //        _cdataStack = new Stack();
 532         //        _cdataStack.push(new Integer(-1)); // push dummy value
 533     }
 534 
 535     /**
 536      * Returns the character encoding to be used in the output document.
 537      * @return the character encoding to be used in the output document.
 538      */
 539     public String getEncoding()
 540     {
 541         return m_encoding;
 542     }
 543 
 544    /**
 545      * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
 546      * @param m_encoding the character encoding
 547      */
 548     public void setEncoding(String m_encoding)
 549     {
 550         this.m_encoding = m_encoding;
 551     }
 552 
 553     /**
 554      * Sets the value coming from the xsl:output omit-xml-declaration stylesheet attribute
 555      * @param b true if the XML declaration is to be omitted from the output
 556      * document.
 557      */
 558     public void setOmitXMLDeclaration(boolean b)
 559     {
 560         this.m_shouldNotWriteXMLHeader = b;

 561     }
 562 
 563 
 564     /**
 565      * @return true if the XML declaration is to be omitted from the output
 566      * document.
 567      */
 568     public boolean getOmitXMLDeclaration()
 569     {
 570         return m_shouldNotWriteXMLHeader;
 571     }
 572 
 573     /**
 574      * Returns the previously set value of the value to be used as the public
 575      * identifier in the document type declaration (DTD).
 576      *
 577      *@return the public identifier to be used in the DOCTYPE declaration in the
 578      * output document.
 579      */
 580     public String getDoctypePublic()
 581     {
 582         return m_doctypePublic;
 583     }
 584 
 585     /** Set the value coming from the xsl:output doctype-public stylesheet attribute.
 586       * @param doctypePublic the public identifier to be used in the DOCTYPE
 587       * declaration in the output document.
 588       */
 589     public void setDoctypePublic(String doctypePublic)
 590     {
 591         this.m_doctypePublic = doctypePublic;
 592     }
 593 
 594 
 595     /**
 596      * Returns the previously set value of the value to be used
 597      * as the system identifier in the document type declaration (DTD).
 598          * @return the system identifier to be used in the DOCTYPE declaration in
 599          * the output document.
 600      *
 601      */
 602     public String getDoctypeSystem()
 603     {
 604         return m_doctypeSystem;
 605     }
 606 
 607     /** Set the value coming from the xsl:output doctype-system stylesheet attribute.
 608       * @param doctypeSystem the system identifier to be used in the DOCTYPE
 609       * declaration in the output document.
 610       */
 611     public void setDoctypeSystem(String doctypeSystem)
 612     {
 613         this.m_doctypeSystem = doctypeSystem;
 614     }
 615 
 616     /** Set the value coming from the xsl:output doctype-public and doctype-system stylesheet properties
 617      * @param doctypeSystem the system identifier to be used in the DOCTYPE
 618      * declaration in the output document.
 619      * @param doctypePublic the public identifier to be used in the DOCTYPE
 620      * declaration in the output document.
 621      */
 622     public void setDoctype(String doctypeSystem, String doctypePublic)
 623     {
 624         this.m_doctypeSystem = doctypeSystem;
 625         this.m_doctypePublic = doctypePublic;
 626     }
 627 
 628     /**
 629      * Sets the value coming from the xsl:output standalone stylesheet attribute.
 630      * @param standalone a value of "yes" indicates that the
 631      * <code>standalone</code> delaration is to be included in the output
 632      * document. This method remembers if the value was explicitly set using
 633      * this method, verses if the value is the default value.
 634      */
 635     public void setStandalone(String standalone)
 636     {
 637         if (standalone != null)
 638         {
 639             m_standaloneWasSpecified = true;
 640             setStandaloneInternal(standalone);
 641         }
 642     }

 643     /**
 644      * Sets the XSL standalone attribute, but does not remember if this is a
 645      * default or explicite setting.
 646      * @param standalone "yes" | "no"
 647      */
 648     protected void setStandaloneInternal(String standalone)
 649     {
 650         if ("yes".equals(standalone))
 651             m_standalone = "yes";
 652         else
 653             m_standalone = "no";
 654 
 655     }
 656 
 657     /**
 658      * Gets the XSL standalone attribute
 659      * @return a value of "yes" if the <code>standalone</code> delaration is to
 660      * be included in the output document.
 661      *  @see XSLOutputAttributes#getStandalone()
 662      */


 683     {
 684         return m_mediatype;
 685     }
 686 
 687     /**
 688      * Gets the version of the output format.
 689      * @return the version of the output format.
 690      */
 691     public String getVersion()
 692     {
 693         return m_version;
 694     }
 695 
 696     /**
 697      * Sets the value coming from the xsl:output version attribute.
 698      * @param version the version of the output format.
 699      * @see SerializationHandler#setVersion(String)
 700      */
 701     public void setVersion(String version)
 702     {
 703         m_version = version;
 704     }
 705 
 706     /**
 707      * Sets the value coming from the xsl:output media-type stylesheet attribute.
 708      * @param mediaType the non-null media-type or MIME type associated with the
 709      * output document.
 710      * @see javax.xml.transform.OutputKeys#MEDIA_TYPE
 711      * @see SerializationHandler#setMediaType(String)
 712      */
 713     public void setMediaType(String mediaType)
 714     {
 715         m_mediatype = mediaType;
 716     }
 717 
 718     /**
 719      * @return the number of spaces to indent for each indentation level.
 720      */
 721     public int getIndentAmount()
 722     {
 723         return m_indentAmount;
 724     }
 725 
 726     /**
 727      * Sets the indentation amount.
 728      * @param m_indentAmount The m_indentAmount to set
 729      */
 730     public void setIndentAmount(int m_indentAmount)
 731     {
 732         this.m_indentAmount = m_indentAmount;
 733     }
 734 
 735     /**
 736      * Sets the value coming from the xsl:output indent stylesheet
 737      * attribute.
 738      * @param doIndent true if the output document should be indented to
 739      * visually indicate its structure.
 740      * @see XSLOutputAttributes#setIndent(boolean)
 741      */
 742     public void setIndent(boolean doIndent)
 743     {
 744         m_doIndent = doIndent;

 745     }
 746 
 747     /**
 748      * Sets the isStandalone property
 749      * @param isStandalone true if the ORACLE_IS_STANDALONE is set to yes
 750      * @see OutputPropertiesFactory ORACLE_IS_STANDALONE
 751      */
 752     public void setIsStandalone(boolean isStandalone)
 753     {
 754        m_isStandalone = isStandalone;
 755     }
 756 
 757     /**
 758      * This method is used when a prefix/uri namespace mapping
 759      * is indicated after the element was started with a
 760      * startElement() and before and endElement().
 761      * startPrefixMapping(prefix,uri) would be used before the
 762      * startElement() call.
 763      * @param uri the URI of the namespace
 764      * @param prefix the prefix associated with the given URI.


 770     {
 771         // default behavior is to do nothing
 772     }
 773 
 774     /**
 775      * Return a {@link DOMSerializer} interface into this serializer. If the
 776      * serializer does not support the {@link DOMSerializer} interface, it should
 777      * return null.
 778      *
 779      * @return A {@link DOMSerializer} interface into this serializer,  or null
 780      * if the serializer is not DOM capable
 781      * @throws IOException An I/O exception occured
 782      * @see Serializer#asDOMSerializer()
 783      */
 784     public DOMSerializer asDOMSerializer() throws IOException
 785     {
 786         return this;
 787     }
 788 
 789     /**
 790      * Push a boolean state based on if the name of the current element
 791      * is found in the list of qnames.  A state is only pushed if
 792      * there were some cdata-section-names were specified.
 793      * <p>
 794      * Hidden parameters are the vector of qualified elements specified in
 795      * cdata-section-names attribute, and the m_cdataSectionStates stack
 796      * onto which whether the current element is in the list is pushed (true or
 797      * false). Other hidden parameters are the current elements namespaceURI,
 798      * localName and qName
 799      */
 800     protected boolean isCdataSection()
 801     {
 802 
 803         boolean b = false;
 804 
 805         if (null != m_cdataSectionElements)
 806         {
 807             if (m_elemContext.m_elementLocalName == null)
 808                 m_elemContext.m_elementLocalName =
 809                     getLocalName(m_elemContext.m_elementName);
 810             if (m_elemContext.m_elementURI == null)
 811             {
 812                 String prefix = getPrefixPart(m_elemContext.m_elementName);
 813                 if (prefix != null)
 814                     m_elemContext.m_elementURI =
 815                         m_prefixMap.lookupNamespace(prefix);
 816 
 817             }
 818 
 819             if ((null != m_elemContext.m_elementURI)
 820                 && m_elemContext.m_elementURI.length() == 0)
 821                 m_elemContext.m_elementURI = null;
 822 
 823             int nElems = m_cdataSectionElements.size();
 824 
 825             // loop through 2 at a time, as these are pairs of URI and localName
 826             for (int i = 0; i < nElems; i += 2)
 827             {
 828                 String uri = (String) m_cdataSectionElements.elementAt(i);
 829                 String loc = (String) m_cdataSectionElements.elementAt(i + 1);
 830                 if (loc.equals(m_elemContext.m_elementLocalName)
 831                     && subPartMatch(m_elemContext.m_elementURI, uri))
 832                 {
 833                     b = true;
 834 
 835                     break;
 836                 }
 837             }
 838         }
 839         return b;
 840     }
 841 
 842     /**
 843      * Tell if two strings are equal, without worry if the first string is null.
 844      *
 845      * @param p String reference, which may be null.
 846      * @param t String reference, which may be null.
 847      *
 848      * @return true if strings are equal.
 849      */
 850     private static final boolean subPartMatch(String p, String t)
 851     {
 852         return (p == t) || ((null != p) && (p.equals(t)));
 853     }
 854 
 855     /**
 856      * Returns the local name of a qualified name.
 857      * If the name has no prefix,
 858      * then it works as the identity (SAX2).
 859      *
 860      * @param qname a qualified name
 861      * @return returns the prefix of the qualified name,
 862      * or null if there is no prefix.


1295      *
1296      * @param mappings NamespaceMappings
1297      */
1298     public void setNamespaceMappings(NamespaceMappings mappings) {
1299         m_prefixMap = mappings;
1300     }
1301 
1302     public boolean reset()
1303     {
1304         resetSerializerBase();
1305         return true;
1306     }
1307 
1308     /**
1309      * Reset all of the fields owned by SerializerBase
1310      *
1311      */
1312     private void resetSerializerBase()
1313     {
1314         this.m_attributes.clear();
1315         this.m_cdataSectionElements = null;
1316         this.m_elemContext = new ElemContext();
1317         this.m_doctypePublic = null;
1318         this.m_doctypeSystem = null;
1319         this.m_doIndent = false;
1320         this.m_encoding = null;
1321         this.m_indentAmount = 0;
1322         this.m_inEntityRef = false;
1323         this.m_inExternalDTD = false;
1324         this.m_mediatype = null;
1325         this.m_needToCallStartDocument = true;
1326         this.m_needToOutputDocTypeDecl = false;
1327         if (this.m_prefixMap != null)
1328             this.m_prefixMap.reset();
1329         this.m_shouldNotWriteXMLHeader = false;
1330         this.m_sourceLocator = null;
1331         this.m_standalone = null;
1332         this.m_standaloneWasSpecified = false;
1333         this.m_tracer = null;
1334         this.m_transformer = null;
1335         this.m_version = null;
1336         // don't set writer to null, so that it might be re-used
1337         //this.m_writer = null;
1338     }
1339 
1340     /**


1382      */
1383     public void unparsedEntityDecl(
1384         String arg0,
1385         String arg1,
1386         String arg2,
1387         String arg3)
1388         throws SAXException {
1389         // This method just provides a definition to satisfy the interface
1390         // A particular sub-class of SerializerBase provides the implementation (if desired)
1391     }
1392 
1393     /**
1394      * If set to false the serializer does not expand DTD entities,
1395      * but leaves them as is, the default value is true.
1396      */
1397     public void setDTDEntityExpansion(boolean expand) {
1398         // This method just provides a definition to satisfy the interface
1399         // A particular sub-class of SerializerBase provides the implementation (if desired)
1400     }
1401 









































































































































































































































































































































1402 }
   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one
   7  * or more contributor license agreements. See the NOTICE file
   8  * distributed with this work for additional information
   9  * regarding copyright ownership. The ASF licenses this file
  10  * to you under the Apache License, Version 2.0 (the  "License");
  11  * you may not use this file except in compliance with the License.
  12  * You may obtain a copy of the License at
  13  *
  14  *     http://www.apache.org/licenses/LICENSE-2.0
  15  *
  16  * Unless required by applicable law or agreed to in writing, software
  17  * distributed under the License is distributed on an "AS IS" BASIS,
  18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19  * See the License for the specific language governing permissions and
  20  * limitations under the License.
  21  */
  22 /*
  23  * $Id: SerializerBase.java,v 1.5 2006/04/14 12:09:19 sunithareddy Exp $
  24  */
  25 package com.sun.org.apache.xml.internal.serializer;
  26 
  27 import java.io.IOException;
  28 import java.util.HashMap;
  29 import java.util.Set;
  30 import java.util.ArrayList;
  31  
  32 import javax.xml.transform.OutputKeys;
  33 import javax.xml.transform.SourceLocator;
  34 import javax.xml.transform.Transformer;
  35 
  36 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
  37 import com.sun.org.apache.xml.internal.serializer.utils.Utils;
  38 import org.xml.sax.Attributes;
  39 import org.xml.sax.ContentHandler;
  40 import org.xml.sax.Locator;
  41 import org.xml.sax.SAXException;
  42 import org.xml.sax.SAXParseException;
  43 import org.xml.sax.ext.Locator2;
  44 
  45 
  46 /**
  47  * This class acts as a base class for the XML "serializers"
  48  * and the stream serializers.
  49  * It contains a number of common fields and methods.
  50  *
  51  * @xsl.usage internal
  52  */


  96     protected boolean m_cdataTagOpen = false;
  97 
  98     /**
  99      * All the attributes of the current element, collected from
 100      * startPrefixMapping() calls, or addAddtribute() calls, or
 101      * from the SAX attributes in a startElement() call.
 102      */
 103     protected AttributesImplSerializer m_attributes = new AttributesImplSerializer();
 104 
 105     /**
 106      * Tells if we're in an EntityRef event.
 107      */
 108     protected boolean m_inEntityRef = false;
 109 
 110     /** This flag is set while receiving events from the external DTD */
 111     protected boolean m_inExternalDTD = false;
 112 
 113     /**
 114      * The System ID for the doc type.
 115      */
 116     protected String m_doctypeSystem;
 117 
 118     /**
 119      * The public ID for the doc type.
 120      */
 121     protected String m_doctypePublic;
 122 
 123     /**
 124      * Flag to tell that we need to add the doctype decl, which we can't do
 125      * until the first element is encountered.
 126      */
 127     boolean m_needToOutputDocTypeDecl = true;
 128 
 129     /**






 130      * Tells if we should write the XML declaration.
 131      */
 132     protected boolean m_shouldNotWriteXMLHeader = false;
 133 
 134     /**
 135      * The standalone value for the doctype.
 136      */
 137     private String m_standalone;
 138 
 139     /**
 140      * True if standalone was specified.
 141      */
 142     protected boolean m_standaloneWasSpecified = false;
 143 
 144     /**
 145      * Determine if the output is a standalone.
 146      */
 147     protected boolean m_isStandalone = false;
 148 
 149     /**
 150      * Flag to tell if indenting (pretty-printing) is on.
 151      */
 152     protected boolean m_doIndent = false;
 153     /**
 154      * Amount to indent.
 155      */
 156     protected int m_indentAmount = 0;
 157 
 158     /**
 159      * Tells the XML version, for writing out to the XML decl.
 160      */
 161     protected String m_version = null;
 162 
 163     /**
 164      * The mediatype.  Not used right now.
 165      */
 166     protected String m_mediatype;
 167 
 168     /**
 169      * The transformer that was around when this output handler was created (if
 170      * any).
 171      */
 172     private Transformer m_transformer;
 173 
 174     /**







 175      * Namespace support, that keeps track of currently defined
 176      * prefix/uri mappings. As processed elements come and go, so do
 177      * the associated mappings for that element.
 178      */
 179     protected NamespaceMappings m_prefixMap;
 180 
 181     /**
 182      * Handle for firing generate events.  This interface may be implemented
 183      * by the referenced transformer object.
 184      */
 185     protected SerializerTrace m_tracer;
 186 
 187     protected SourceLocator m_sourceLocator;
 188 
 189 
 190     /**
 191      * The writer to send output to. This field is only used in the ToStream
 192      * serializers, but exists here just so that the fireStartDoc() and
 193      * other fire... methods can flush this writer when tracing.
 194      */


 513     {
 514         // do nothing (base behavior)
 515     }
 516 
 517     /**
 518      * Initialize global variables
 519      */
 520     protected void initCDATA()
 521     {
 522         // CDATA stack
 523         //        _cdataStack = new Stack();
 524         //        _cdataStack.push(new Integer(-1)); // push dummy value
 525     }
 526 
 527     /**
 528      * Returns the character encoding to be used in the output document.
 529      * @return the character encoding to be used in the output document.
 530      */
 531     public String getEncoding()
 532     {
 533         return getOutputProperty(OutputKeys.ENCODING);
 534     }
 535 
 536    /**
 537      * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
 538      * @param m_encoding the character encoding
 539      */
 540     public void setEncoding(String encoding)
 541     {
 542         setOutputProperty(OutputKeys.ENCODING,encoding);
 543     }
 544 
 545     /**
 546      * Sets the value coming from the xsl:output omit-xml-declaration stylesheet attribute
 547      * @param b true if the XML declaration is to be omitted from the output
 548      * document.
 549      */
 550     public void setOmitXMLDeclaration(boolean b)
 551     {
 552         String val = b ? "yes":"no";
 553         setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,val);
 554     }
 555 
 556 
 557     /**
 558      * @return true if the XML declaration is to be omitted from the output
 559      * document.
 560      */
 561     public boolean getOmitXMLDeclaration()
 562     {
 563         return m_shouldNotWriteXMLHeader;
 564     }
 565 
 566     /**
 567      * Returns the previously set value of the value to be used as the public
 568      * identifier in the document type declaration (DTD).
 569      *
 570      *@return the public identifier to be used in the DOCTYPE declaration in the
 571      * output document.
 572      */
 573     public String getDoctypePublic()
 574     {
 575         return m_doctypePublic;
 576     }
 577 
 578     /** Set the value coming from the xsl:output doctype-public stylesheet attribute.
 579       * @param doctypePublic the public identifier to be used in the DOCTYPE
 580       * declaration in the output document.
 581       */
 582     public void setDoctypePublic(String doctypePublic)
 583     {
 584         setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
 585     }
 586 
 587 
 588     /**
 589      * Returns the previously set value of the value to be used
 590      * as the system identifier in the document type declaration (DTD).
 591          * @return the system identifier to be used in the DOCTYPE declaration in
 592          * the output document.
 593      *
 594      */
 595     public String getDoctypeSystem()
 596     {
 597         return m_doctypeSystem;
 598     }
 599 
 600     /** Set the value coming from the xsl:output doctype-system stylesheet attribute.
 601       * @param doctypeSystem the system identifier to be used in the DOCTYPE
 602       * declaration in the output document.
 603       */
 604     public void setDoctypeSystem(String doctypeSystem)
 605     {
 606         setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
 607     }
 608 
 609     /** Set the value coming from the xsl:output doctype-public and doctype-system stylesheet properties
 610      * @param doctypeSystem the system identifier to be used in the DOCTYPE
 611      * declaration in the output document.
 612      * @param doctypePublic the public identifier to be used in the DOCTYPE
 613      * declaration in the output document.
 614      */
 615     public void setDoctype(String doctypeSystem, String doctypePublic)
 616     {
 617         setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
 618         setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
 619     }
 620 
 621     /**
 622      * Sets the value coming from the xsl:output standalone stylesheet attribute.
 623      * @param standalone a value of "yes" indicates that the
 624      * <code>standalone</code> delaration is to be included in the output
 625      * document. This method remembers if the value was explicitly set using
 626      * this method, verses if the value is the default value.
 627      */
 628     public void setStandalone(String standalone)
 629     {
 630         setOutputProperty(OutputKeys.STANDALONE, standalone);




 631     }
 632     
 633     /**
 634      * Sets the XSL standalone attribute, but does not remember if this is a
 635      * default or explicite setting.
 636      * @param standalone "yes" | "no"
 637      */
 638     protected void setStandaloneInternal(String standalone)
 639     {
 640         if ("yes".equals(standalone))
 641             m_standalone = "yes";
 642         else
 643             m_standalone = "no";
 644 
 645     }
 646 
 647     /**
 648      * Gets the XSL standalone attribute
 649      * @return a value of "yes" if the <code>standalone</code> delaration is to
 650      * be included in the output document.
 651      *  @see XSLOutputAttributes#getStandalone()
 652      */


 673     {
 674         return m_mediatype;
 675     }
 676 
 677     /**
 678      * Gets the version of the output format.
 679      * @return the version of the output format.
 680      */
 681     public String getVersion()
 682     {
 683         return m_version;
 684     }
 685 
 686     /**
 687      * Sets the value coming from the xsl:output version attribute.
 688      * @param version the version of the output format.
 689      * @see SerializationHandler#setVersion(String)
 690      */
 691     public void setVersion(String version)
 692     {
 693         setOutputProperty(OutputKeys.VERSION, version);
 694     }
 695 
 696     /**
 697      * Sets the value coming from the xsl:output media-type stylesheet attribute.
 698      * @param mediaType the non-null media-type or MIME type associated with the
 699      * output document.
 700      * @see javax.xml.transform.OutputKeys#MEDIA_TYPE
 701      * @see SerializationHandler#setMediaType(String)
 702      */
 703     public void setMediaType(String mediaType)
 704     {
 705         setOutputProperty(OutputKeys.MEDIA_TYPE,mediaType);
 706     }
 707 
 708     /**
 709      * @return the number of spaces to indent for each indentation level.
 710      */
 711     public int getIndentAmount()
 712     {
 713         return m_indentAmount;
 714     }
 715 
 716     /**
 717      * Sets the indentation amount.
 718      * @param m_indentAmount The m_indentAmount to set
 719      */
 720     public void setIndentAmount(int m_indentAmount)
 721     {
 722         this.m_indentAmount = m_indentAmount;
 723     }
 724 
 725     /**
 726      * Sets the value coming from the xsl:output indent stylesheet
 727      * attribute.
 728      * @param doIndent true if the output document should be indented to
 729      * visually indicate its structure.
 730      * @see XSLOutputAttributes#setIndent(boolean)
 731      */
 732     public void setIndent(boolean doIndent)
 733     {
 734         String val = doIndent ? "yes":"no";
 735         setOutputProperty(OutputKeys.INDENT,val);
 736     }
 737 
 738     /**
 739      * Sets the isStandalone property
 740      * @param isStandalone true if the ORACLE_IS_STANDALONE is set to yes
 741      * @see OutputPropertiesFactory ORACLE_IS_STANDALONE
 742      */
 743     public void setIsStandalone(boolean isStandalone)
 744     {
 745        m_isStandalone = isStandalone;
 746     }
 747 
 748     /**
 749      * This method is used when a prefix/uri namespace mapping
 750      * is indicated after the element was started with a
 751      * startElement() and before and endElement().
 752      * startPrefixMapping(prefix,uri) would be used before the
 753      * startElement() call.
 754      * @param uri the URI of the namespace
 755      * @param prefix the prefix associated with the given URI.


 761     {
 762         // default behavior is to do nothing
 763     }
 764 
 765     /**
 766      * Return a {@link DOMSerializer} interface into this serializer. If the
 767      * serializer does not support the {@link DOMSerializer} interface, it should
 768      * return null.
 769      *
 770      * @return A {@link DOMSerializer} interface into this serializer,  or null
 771      * if the serializer is not DOM capable
 772      * @throws IOException An I/O exception occured
 773      * @see Serializer#asDOMSerializer()
 774      */
 775     public DOMSerializer asDOMSerializer() throws IOException
 776     {
 777         return this;
 778     }
 779 
 780     /**





















































 781      * Tell if two strings are equal, without worry if the first string is null.
 782      *
 783      * @param p String reference, which may be null.
 784      * @param t String reference, which may be null.
 785      *
 786      * @return true if strings are equal.
 787      */
 788     private static final boolean subPartMatch(String p, String t)
 789     {
 790         return (p == t) || ((null != p) && (p.equals(t)));
 791     }
 792 
 793     /**
 794      * Returns the local name of a qualified name.
 795      * If the name has no prefix,
 796      * then it works as the identity (SAX2).
 797      *
 798      * @param qname a qualified name
 799      * @return returns the prefix of the qualified name,
 800      * or null if there is no prefix.


1233      *
1234      * @param mappings NamespaceMappings
1235      */
1236     public void setNamespaceMappings(NamespaceMappings mappings) {
1237         m_prefixMap = mappings;
1238     }
1239 
1240     public boolean reset()
1241     {
1242         resetSerializerBase();
1243         return true;
1244     }
1245 
1246     /**
1247      * Reset all of the fields owned by SerializerBase
1248      *
1249      */
1250     private void resetSerializerBase()
1251     {
1252         this.m_attributes.clear();
1253         this.m_StringOfCDATASections = null;
1254         this.m_elemContext = new ElemContext();
1255         this.m_doctypePublic = null;
1256         this.m_doctypeSystem = null;
1257         this.m_doIndent = false;

1258         this.m_indentAmount = 0;
1259         this.m_inEntityRef = false;
1260         this.m_inExternalDTD = false;
1261         this.m_mediatype = null;
1262         this.m_needToCallStartDocument = true;
1263         this.m_needToOutputDocTypeDecl = false;
1264         if (this.m_prefixMap != null)
1265             this.m_prefixMap.reset();
1266         this.m_shouldNotWriteXMLHeader = false;
1267         this.m_sourceLocator = null;
1268         this.m_standalone = null;
1269         this.m_standaloneWasSpecified = false;
1270         this.m_tracer = null;
1271         this.m_transformer = null;
1272         this.m_version = null;
1273         // don't set writer to null, so that it might be re-used
1274         //this.m_writer = null;
1275     }
1276 
1277     /**


1319      */
1320     public void unparsedEntityDecl(
1321         String arg0,
1322         String arg1,
1323         String arg2,
1324         String arg3)
1325         throws SAXException {
1326         // This method just provides a definition to satisfy the interface
1327         // A particular sub-class of SerializerBase provides the implementation (if desired)
1328     }
1329 
1330     /**
1331      * If set to false the serializer does not expand DTD entities,
1332      * but leaves them as is, the default value is true.
1333      */
1334     public void setDTDEntityExpansion(boolean expand) {
1335         // This method just provides a definition to satisfy the interface
1336         // A particular sub-class of SerializerBase provides the implementation (if desired)
1337     }
1338  
1339 
1340     /** 
1341      * The CDATA section names stored in a whitespace separateed list with
1342      * each element being a word of the form "{uri}localName" This list
1343      * comes from the cdata-section-elements attribute.
1344      * 
1345      * This field replaces m_cdataSectionElements Vector.
1346      */
1347     protected String m_StringOfCDATASections = null; 
1348     
1349     boolean m_docIsEmpty = true;
1350     void initCdataElems(String s)
1351     {
1352         if (s != null)
1353         {            
1354             int max = s.length();
1355 
1356             // true if we are in the middle of a pair of curly braces that delimit a URI
1357             boolean inCurly = false;
1358 
1359             // true if we found a URI but haven't yet processed the local name 
1360             boolean foundURI = false;
1361 
1362             StringBuilder buf = new StringBuilder();
1363             String uri = null;
1364             String localName = null;
1365 
1366             // parse through string, breaking on whitespaces.  I do this instead
1367             // of a tokenizer so I can track whitespace inside of curly brackets,
1368             // which theoretically shouldn't happen if they contain legal URLs.
1369             for (int i = 0; i < max; i++)
1370             {
1371                 char c = s.charAt(i);
1372 
1373                 if (Character.isWhitespace(c))
1374                 {
1375                     if (!inCurly)
1376                     {
1377                         if (buf.length() > 0)
1378                         {
1379                             localName = buf.toString();
1380                             if (!foundURI)
1381                                 uri = "";
1382                             addCDATAElement(uri,localName);
1383                             buf.setLength(0);
1384                             foundURI = false;
1385                         }
1386                         continue;
1387                     }
1388                     else
1389                         buf.append(c); // add whitespace to the URI
1390                 }
1391                 else if ('{' == c) // starting a URI
1392                     inCurly = true;
1393                 else if ('}' == c)
1394                 {
1395                     // we just ended a URI
1396                     foundURI = true;
1397                     uri = buf.toString();
1398                     buf.setLength(0);
1399                     inCurly = false;
1400                 }
1401                 else
1402                 {
1403                     // append non-whitespace, non-curly to current URI or localName being gathered.                    
1404                     buf.append(c);
1405                 }
1406 
1407             }
1408 
1409             if (buf.length() > 0)
1410             {
1411                 // We have one last localName to process.
1412                 localName = buf.toString();
1413                 if (!foundURI)
1414                     uri = "";
1415                 addCDATAElement(uri,localName);
1416             }
1417         }
1418     }
1419     
1420     protected java.util.HashMap<String, HashMap<String, String>> m_CdataElems = null;
1421     private void addCDATAElement(String uri, String localName) 
1422     {
1423         if (m_CdataElems == null) {
1424             m_CdataElems = new java.util.HashMap<>();
1425         }
1426         
1427         HashMap<String,String> h = m_CdataElems.get(localName);
1428         if (h == null) {
1429             h = new HashMap<>();
1430             m_CdataElems.put(localName,h);
1431         }
1432         h.put(uri,uri);
1433         
1434     }
1435     
1436     
1437     /**
1438      * Return true if nothing has been sent to this result tree yet.
1439      * <p>
1440      * This is not a public API.
1441      * 
1442      * @xsl.usage internal
1443      */
1444     public boolean documentIsEmpty() {
1445         // If we haven't called startDocument() yet, then this document is empty
1446         return m_docIsEmpty && (m_elemContext.m_currentElemDepth == 0);
1447     }    
1448     
1449     /**
1450      * Return true if the current element in m_elemContext
1451      * is a CDATA section.
1452      * CDATA sections are specified in the <xsl:output> attribute
1453      * cdata-section-names or in the JAXP equivalent property.
1454      * In any case the format of the value of such a property is:
1455      * <pre>
1456      * "{uri1}localName1 {uri2}localName2 . . . "
1457      * </pre>
1458      * 
1459      * <p>
1460      * This method is not a public API, but is only used internally by the serializer.
1461      */
1462     protected boolean isCdataSection() {
1463         boolean b = false;
1464 
1465         if (null != m_StringOfCDATASections) {
1466             if (m_elemContext.m_elementLocalName == null) {
1467                 String localName =  getLocalName(m_elemContext.m_elementName); 
1468                 m_elemContext.m_elementLocalName = localName;                   
1469             }
1470             
1471             if ( m_elemContext.m_elementURI == null) {
1472                 
1473                 m_elemContext.m_elementURI = getElementURI();
1474             }
1475             else if ( m_elemContext.m_elementURI.length() == 0) {
1476                 if ( m_elemContext.m_elementName == null) {
1477                     m_elemContext.m_elementName = m_elemContext.m_elementLocalName;    
1478                     // leave URI as "", meaning in no namespace
1479                 }
1480                 else if (m_elemContext.m_elementLocalName.length() < m_elemContext.m_elementName.length()){
1481                     // We were told the URI was "", yet the name has a prefix since the name is longer than the localname.
1482                     // So we will fix that incorrect information here.
1483                     m_elemContext.m_elementURI = getElementURI();  
1484                 }
1485             }
1486 
1487             HashMap<String, String> h = null;
1488             if (m_CdataElems != null) {
1489                 h = m_CdataElems.get(m_elemContext.m_elementLocalName);
1490             }
1491             if (h != null) {
1492                 Object obj = h.get(m_elemContext.m_elementURI);
1493                 if (obj != null)
1494                     b = true; 
1495             }
1496 
1497         }
1498         return b;
1499     }
1500     
1501     /**
1502      * Before this call m_elementContext.m_elementURI is null,
1503      * which means it is not yet known. After this call it
1504      * is non-null, but possibly "" meaning that it is in the
1505      * default namespace.
1506      * 
1507      * @return The URI of the element, never null, but possibly "".
1508      */
1509     private String getElementURI() {
1510         String uri = null;
1511         // At this point in processing we have received all the
1512         // namespace mappings
1513         // As we still don't know the elements namespace,
1514         // we now figure it out.
1515 
1516         String prefix = getPrefixPart(m_elemContext.m_elementName);
1517 
1518         if (prefix == null) {
1519             // no prefix so lookup the URI of the default namespace
1520             uri = m_prefixMap.lookupNamespace("");
1521         } else {
1522             uri = m_prefixMap.lookupNamespace(prefix);
1523         }
1524         if (uri == null) {
1525             // We didn't find the namespace for the
1526             // prefix ... ouch, that shouldn't happen.
1527             // This is a hack, we really don't know
1528             // the namespace
1529             uri = EMPTYSTRING;
1530         }
1531 
1532         return uri;
1533     }
1534     
1535 
1536     /**
1537      * Get the value of an output property,
1538      * the explicit value, if any, otherwise the
1539      * default value, if any, otherwise null.
1540      */
1541     public String getOutputProperty(String name) {
1542         String val = getOutputPropertyNonDefault(name);
1543         // If no explicit value, try to get the default value
1544         if (val == null)
1545             val = getOutputPropertyDefault(name);
1546         return val;
1547         
1548     }
1549     /**
1550      * Get the value of an output property, 
1551      * not the default value. If there is a default
1552      * value, but no non-default value this method
1553      * will return null.
1554      * <p>
1555      * 
1556      */
1557     public String getOutputPropertyNonDefault(String name) {
1558         return getProp(name,false);
1559     }
1560     
1561     /**
1562      * Get the default value of an xsl:output property,
1563      * which would be null only if no default value exists
1564      * for the property.
1565      */
1566     public String getOutputPropertyDefault(String name) {
1567         return getProp(name, true);
1568     } 
1569     
1570     /**
1571      * Set the value for the output property, typically from
1572      * an xsl:output element, but this does not change what
1573      * the default value is.
1574      */
1575     public void setOutputProperty(String name, String val) {
1576         setProp(name,val,false);
1577     }
1578     
1579     /**
1580      * Set the default value for an output property, but this does
1581      * not impact any explicitly set value.
1582      */
1583     public void setOutputPropertyDefault(String name, String val) {
1584         setProp(name,val,true);
1585         
1586     }
1587     
1588     /**
1589      * A mapping of keys to explicitly set values, for example if 
1590      * and <xsl:output/> has an "encoding" attribute, this
1591      * map will have what that attribute maps to.
1592      */
1593     private HashMap<String, String> m_OutputProps;
1594     /**
1595      * A mapping of keys to default values, for example if
1596      * the default value of the encoding is "UTF-8" then this
1597      * map will have that "encoding" maps to "UTF-8".
1598      */
1599     private HashMap<String, String> m_OutputPropsDefault;
1600     
1601     Set<String> getOutputPropDefaultKeys() {
1602         return m_OutputPropsDefault.keySet();
1603     }
1604     Set<String> getOutputPropKeys() {
1605         return m_OutputProps.keySet();
1606     }
1607     
1608     private String getProp(String name, boolean defaultVal) {
1609         if (m_OutputProps == null) {
1610             m_OutputProps = new HashMap<>();
1611             m_OutputPropsDefault = new HashMap<>();
1612         }
1613         
1614         String val;
1615         if (defaultVal)
1616             val = m_OutputPropsDefault.get(name);
1617         else
1618             val = m_OutputProps.get(name);
1619         
1620         return val;
1621     }
1622     /**
1623      * 
1624      * @param name The name of the property, e.g. "{http://myprop}indent-tabs" or "indent".
1625      * @param val The value of the property, e.g. "4"
1626      * @param defaultVal true if this is a default value being set for the property as 
1627      * opposed to a user define on, set say explicitly in the stylesheet or via JAXP
1628      */
1629     void setProp(String name, String val, boolean defaultVal) {
1630         if (m_OutputProps == null) {
1631             m_OutputProps = new HashMap<>();
1632             m_OutputPropsDefault = new HashMap<>();
1633         }
1634         
1635         if (defaultVal)
1636             m_OutputPropsDefault.put(name,val);
1637         else {
1638             if (OutputKeys.CDATA_SECTION_ELEMENTS.equals(name) && val != null) {
1639                 initCdataElems(val);
1640                 String oldVal = m_OutputProps.get(name);
1641                 String newVal;
1642                 if (oldVal == null)
1643                     newVal = oldVal + ' ' + val;
1644                 else
1645                     newVal = val;
1646                 m_OutputProps.put(name,newVal);
1647             }
1648             else {
1649                 m_OutputProps.put(name,val);
1650             }
1651         }
1652     }
1653 
1654     /**
1655      * Get the first char of the local name
1656      * @param name Either a local name, or a local name
1657      * preceeded by a uri enclosed in curly braces.
1658      */
1659     static char getFirstCharLocName(String name) {
1660         final char first;
1661         int i = name.indexOf('}');
1662         if (i < 0)
1663             first = name.charAt(0);
1664         else
1665             first = name.charAt(i+1);
1666         return first;
1667     }
1668 }