FileDocCategorySizeDatePackage
ToXMLStream.javaAPI DocJava SE 6 API20359Tue Jun 10 00:23:08 BST 2008None

ToXMLStream

public final class ToXMLStream extends ToStream
This class converts SAX or SAX-like calls to a serialized xml document. The xsl:output method is "xml". This class is used explicitly in code generated by XSLTC, so it is "public", but it should be viewed as internal or package private, this is not an API.
xsl.usage
internal

Fields Summary
boolean
m_cdataTagOpen
remembers if we need to write out "]]>" to close the CDATA
private static CharInfo
m_xmlcharInfo
Map that tells which XML characters should have special treatment, and it provides character to entity name lookup.
Constructors Summary
public ToXMLStream()
Default constructor.


           
     
    
        m_charInfo = m_xmlcharInfo;

        initCDATA();
        // initialize namespaces
        m_prefixMap = new NamespaceMappings();

    
Methods Summary
public voidCopyFrom(com.sun.org.apache.xml.internal.serializer.ToXMLStream xmlListener)
Copy properties from another SerializerToXML.

param
xmlListener non-null reference to a SerializerToXML object.


        m_writer = xmlListener.m_writer;


        // m_outputStream = xmlListener.m_outputStream;
        String encoding = xmlListener.getEncoding();
        setEncoding(encoding);

        setOmitXMLDeclaration(xmlListener.getOmitXMLDeclaration());

        m_ispreserve = xmlListener.m_ispreserve;
        m_preserves = xmlListener.m_preserves;
        m_isprevtext = xmlListener.m_isprevtext;
        m_doIndent = xmlListener.m_doIndent;
        setIndentAmount(xmlListener.getIndentAmount());
        m_startNewLine = xmlListener.m_startNewLine;
        m_needToOutputDocTypeDecl = xmlListener.m_needToOutputDocTypeDecl;
        setDoctypeSystem(xmlListener.getDoctypeSystem());
        setDoctypePublic(xmlListener.getDoctypePublic());        
        setStandalone(xmlListener.getStandalone());
        setMediaType(xmlListener.getMediaType());
        m_maxCharacter = xmlListener.m_maxCharacter;
        m_encodingInfo = xmlListener.m_encodingInfo;
        m_spaceBeforeClose = xmlListener.m_spaceBeforeClose;
        m_cdataStartCalled = xmlListener.m_cdataStartCalled;

    
public voidaddAttribute(java.lang.String uri, java.lang.String localName, java.lang.String rawName, java.lang.String type, java.lang.String value, boolean xslAttribute)
Add an attribute to the current element.

param
uri the URI associated with the element name
param
localName local part of the attribute name
param
rawName prefix:localName
param
type
param
value the value of the attribute
param
xslAttribute true if this attribute is from an xsl:attribute, false if declared within the elements opening tag.
throws
SAXException

        if (m_elemContext.m_startTagOpen)
        {
            boolean was_added = addAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
            

            /*
             * We don't run this block of code if:
             * 1. The attribute value was only replaced (was_added is false).
             * 2. The attribute is from an xsl:attribute element (that is handled
             *    in the addAttributeAlways() call just above.
             * 3. The name starts with "xmlns", i.e. it is a namespace declaration.
             */
            if (was_added && !xslAttribute && !rawName.startsWith("xmlns"))
            {
                String prefixUsed =
                    ensureAttributesNamespaceIsDeclared(
                        uri,
                        localName,
                        rawName);
                if (prefixUsed != null
                    && rawName != null
                    && !rawName.startsWith(prefixUsed))
                {
                    // use a different raw name, with the prefix used in the
                    // generated namespace declaration
                    rawName = prefixUsed + ":" + localName;

                }
            }
            addAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
        }
        else
        {
            /*
             * The startTag is closed, yet we are adding an attribute?
             *
             * Section: 7.1.3 Creating Attributes Adding an attribute to an
             * element after a PI (for example) has been added to it is an
             * error. The attributes can be ignored. The spec doesn't explicitly
             * say this is disallowed, as it does for child elements, but it
             * makes sense to have the same treatment.
             *
             * We choose to ignore the attribute which is added too late.
             */
            // Generate a warning of the ignored attributes

            // Create the warning message
            String msg = Utils.messages.createMessage(
                    MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION,new Object[]{ localName });

            try {
                // Prepare to issue the warning message
                Transformer tran = super.getTransformer();
                ErrorListener errHandler = tran.getErrorListener();


                // Issue the warning message
                if (null != errHandler && m_sourceLocator != null)
                  errHandler.warning(new TransformerException(msg, m_sourceLocator));
                else
                  System.out.println(msg);
                }
            catch (Exception e){}             
        }
    
public voidaddUniqueAttribute(java.lang.String name, java.lang.String value, int flags)
This method is used to add an attribute to the currently open element. The caller has guaranted that this attribute is unique, which means that it not been seen before and will not be seen again.

param
name the qualified name of the attribute
param
value the value of the attribute which can contain only ASCII printable characters characters in the range 32 to 127 inclusive.
param
flags the bit values of this integer give optimization information.

        if (m_elemContext.m_startTagOpen)
        {
           
            try
            {
                final String patchedName = patchName(name);
                final java.io.Writer writer = m_writer;
                if ((flags & NO_BAD_CHARS) > 0 && m_xmlcharInfo.onlyQuotAmpLtGt)
                {
                    // "flags" has indicated that the characters
                    // '>'  '<'   '&'  and '"' are not in the value and
                    // m_htmlcharInfo has recorded that there are no other
                    // entities in the range 32 to 127 so we write out the
                    // value directly
                    
                    writer.write(' ");
                    writer.write(patchedName);
                    writer.write("=\"");
                    writer.write(value);
                    writer.write('"");
                }
                else
                {
                    writer.write(' ");
                    writer.write(patchedName);
                    writer.write("=\"");
                    writeAttrString(writer, value, this.getEncoding());
                    writer.write('"");
                }
            } catch (IOException e) {
                throw new SAXException(e);
            }
        }
    
public voidendDocument()
Receive notification of the end of a document.

throws
org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception.
throws
org.xml.sax.SAXException

        flushPending();
        if (m_doIndent && !m_isprevtext)
        {
            try
            {
            outputLineSep();
            }
            catch(IOException e)
            {
                throw new SAXException(e);
            }
        }

        flushWriter();
        
        if (m_tracer != null)
            super.fireEndDoc();
    
public voidendElement(java.lang.String elemName)

see
ExtendedContentHandler#endElement(String)

        endElement(null, null, elemName);
    
public voidendPreserving()
Ends a whitespace preserving section.

see
#startPreserving
throws
org.xml.sax.SAXException


        // Not sure this is really what we want.  -sb
        m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
    
public voidentityReference(java.lang.String name)
Receive notivication of a entityReference.

param
name The name of the entity.
throws
org.xml.sax.SAXException

        if (m_elemContext.m_startTagOpen)
        {
            closeStartTag();
            m_elemContext.m_startTagOpen = false;
        }

        try
        {
            if (shouldIndent())
                indent();

            final java.io.Writer writer = m_writer;
            writer.write('&");
            writer.write(name);
            writer.write(';");
        }
        catch(IOException e)
        {
            throw new SAXException(e);
        }
        
        if (m_tracer != null)
            super.fireEntityReference(name);            
    
private java.lang.StringgetXMLVersion()
This method checks for the XML version of output document. If XML version of output document is not specified, then output document is of version XML 1.0. If XML version of output doucment is specified, but it is not either XML 1.0 or XML 1.1, a warning message is generated, the XML Version of output document is set to XML 1.0 and processing continues.

return
string (XML version)

        String xmlVersion = getVersion();
        if(xmlVersion == null || xmlVersion.equals(XMLVERSION10))
        {
            xmlVersion = XMLVERSION10;
        }
        else if(xmlVersion.equals(XMLVERSION11))
        {
            xmlVersion = XMLVERSION11;
        }
        else
        {
            String msg = Utils.messages.createMessage(
                               MsgKey.ER_XML_VERSION_NOT_SUPPORTED,new Object[]{ xmlVersion });
            try 
            {
                // Prepare to issue the warning message
                Transformer tran = super.getTransformer();
                ErrorListener errHandler = tran.getErrorListener();
                // Issue the warning message
                if (null != errHandler && m_sourceLocator != null)
                    errHandler.warning(new TransformerException(msg, m_sourceLocator));
                else
                    System.out.println(msg);
            }
            catch (Exception e){}
            xmlVersion = XMLVERSION10;								
        }
        return xmlVersion;
    
public voidnamespaceAfterStartElement(java.lang.String prefix, java.lang.String uri)
This method is used to notify the serializer of a namespace mapping (or node) that applies to the current element whose startElement() call has already been seen. The official SAX startPrefixMapping(prefix,uri) is to define a mapping for a child element that is soon to be seen with a startElement() call. The official SAX call does not apply to the current element, hence the reason for this method.


        // hack for XSLTC with finding URI for default namespace
        if (m_elemContext.m_elementURI == null)
        {
            String prefix1 = getPrefixPart(m_elemContext.m_elementName);
            if (prefix1 == null && EMPTYSTRING.equals(prefix))
            {
                // the elements URI is not known yet, and it
                // doesn't have a prefix, and we are currently
                // setting the uri for prefix "", so we have
                // the uri for the element... lets remember it
                m_elemContext.m_elementURI = uri;
            }
        }            
        startPrefixMapping(prefix,uri,false);
        return;

    
public voidprocessingInstruction(java.lang.String target, java.lang.String data)
Receive notification of a processing instruction.

param
target The processing instruction target.
param
data The processing instruction data, or null if none was supplied.
throws
org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception.
throws
org.xml.sax.SAXException

        if (m_inEntityRef)
            return;
        
        flushPending();   

        if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
        {
            startNonEscaping();
        }
        else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING))
        {
            endNonEscaping();
        }
        else
        {
            try
            {
                if (m_elemContext.m_startTagOpen)
                {
                    closeStartTag();
                    m_elemContext.m_startTagOpen = false;
                }
                else if (m_needToCallStartDocument)
                    startDocumentInternal();                

                if (shouldIndent())
                    indent();

                final java.io.Writer writer = m_writer;
                writer.write("<?");
                writer.write(target);

                if (data.length() > 0
                    && !Character.isSpaceChar(data.charAt(0)))
                    writer.write(' ");

                int indexOfQLT = data.indexOf("?>");

                if (indexOfQLT >= 0)
                {

                    // See XSLT spec on error recovery of "?>" in PIs.
                    if (indexOfQLT > 0)
                    {
                        writer.write(data.substring(0, indexOfQLT));
                    }

                    writer.write("? >"); // add space between.

                    if ((indexOfQLT + 2) < data.length())
                    {
                        writer.write(data.substring(indexOfQLT + 2));
                    }
                }
                else
                {
                    writer.write(data);
                }

                writer.write('?");
                writer.write('>");

                // Always output a newline char if not inside of an
                // element. The whitespace is not significant in that
                // case.
                if (m_elemContext.m_currentElemDepth <= 0)
                    writer.write(m_lineSep, 0, m_lineSepLen);

                m_startNewLine = true;
            }
            catch(IOException e)
            {
                throw new SAXException(e);
            }
        }
        
        if (m_tracer != null)
            super.fireEscapingEvent(target, data);  
    
protected booleanpushNamespace(java.lang.String prefix, java.lang.String uri)
From XSLTC Declare a prefix to point to a namespace URI. Inform SAX handler if this is a new prefix mapping.

        try
        {
            if (m_prefixMap.pushNamespace(
                prefix, uri, m_elemContext.m_currentElemDepth))
            {
                startPrefixMapping(prefix, uri);
                return true;
            }
        }
        catch (SAXException e)
        {
            // falls through
        }
        return false;
    
public booleanreset()
Try's to reset the super class and reset this class for re-use, so that you don't need to create a new serializer (mostly for performance reasons).

return
true if the class was successfuly reset.

        boolean wasReset = false;
        if (super.reset())
        {
            resetToXMLStream();
            wasReset = true;
        }
        return wasReset;
    
private voidresetToXMLStream()
Reset all of the fields owned by ToStream class

        this.m_cdataTagOpen = false;

    
public voidstartDocumentInternal()
Receive notification of the beginning of a document.

throws
org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception.
throws
org.xml.sax.SAXException


        if (m_needToCallStartDocument)
        { 
            super.startDocumentInternal();
            m_needToCallStartDocument = false;

            if (m_inEntityRef)
                return;

            m_needToOutputDocTypeDecl = true;
            m_startNewLine = false;
            /* The call to getXMLVersion() might emit an error message
             * and we should emit this message regardless of if we are 
             * writing out an XML header or not.
             */ 
            if (getOmitXMLDeclaration() == false)
            {
                String encoding = Encodings.getMimeEncoding(getEncoding());
                String version = getVersion();
                if (version == null)
                    version = "1.0";
                String standalone;

                if (m_standaloneWasSpecified)
                {
                    standalone = " standalone=\"" + getStandalone() + "\"";
                }
                else
                {
                    standalone = "";
                }

                try
                {
                    final java.io.Writer writer = m_writer;
                    writer.write("<?xml version=\"");
                    writer.write(version);
                    writer.write("\" encoding=\"");
                    writer.write(encoding);
                    writer.write('\"");
                    writer.write(standalone);
                    writer.write("?>");
                    if (m_doIndent)
                        writer.write(m_lineSep, 0, m_lineSepLen);
                } 
                catch(IOException e)
                {
                    throw new SAXException(e);
                }

            }
        }
    
public voidstartPreserving()
Starts a whitespace preserving section. All characters printed within a preserving section are printed without indentation and without consolidating multiple spaces. This is equivalent to the xml:space="preserve" attribute. Only XML and HTML serializers need to support this method.

The contents of the whitespace preserving section will be delivered through the regular characters event.

throws
org.xml.sax.SAXException


        // Not sure this is really what we want.  -sb
        m_preserves.push(true);

        m_ispreserve = true;