Class AbstractXMLOutputProcessor

  • All Implemented Interfaces:
    XMLOutputProcessor

    public abstract class AbstractXMLOutputProcessor
    extends AbstractOutputProcessor
    implements XMLOutputProcessor
    This class provides a concrete implementation of XMLOutputProcessor for supporting the XMLOutputter2.

    Overview

    This class is marked abstract even though all methods are fully implemented. The process*(...) methods are public because they match the XMLOutputProcessor interface but the remaining methods are all protected.

    People who want to create a custom XMLOutputProcessor for XMLOutputter are able to extend this class and modify any functionality they want. Before sub-classing this you should first check to see if the Format class can get you the results you want.

    Subclasses of this should have reentrant methods. This is easiest to accomplish simply by not allowing any instance fields. If your sub-class has an instance field/variable, then it's probably broken.

    The Stacks

    One significant feature of this implementation is that it creates and maintains both a NamespaceStack and FormatStack that are managed in the printElement(Writer, FormatStack, NamespaceStack, Element) method. The stacks are pushed and popped in that method only. They significantly improve the performance and readability of the code.

    The NamespaceStack is only sent through to the printElement(Writer, FormatStack, NamespaceStack, Element) and printContent(Writer, FormatStack, NamespaceStack, Walker) methods, but the FormatStack is pushed through to all print* Methods.

    Text Processing

    In XML the concept of 'Text' can be loosely defined as anything that can be found between an Element's start and end tags, excluding Comments and Processing Instructions. When considered from a JDOM perspective, this means Text, CDATA and EntityRef content. This will be referred to as 'Text-like content'

    XMLOutputter delegates the management and formatting of Content to a Walker instance. See Walker and its various implementations for details on how the Element content is processed.

    Because the Walker interface specifies that Text/CDATA content may be returned as either Text/CDATA instances or as formatted String values this class sometimes uses printCDATA(...) and printText(...), and sometimes uses the more direct textCDATA(Writer, String) or textRaw(Writer, String) as appropriate. In other words, subclasses should probably override these second methods instead of the print methods.

    Non-Text Content

    Non-text content is processed via the respective print* methods. The usage should be logical based on the method name.

    The general observations are:

    • printElement - maintains the Stacks, prints the element open tags, with attributes and namespaces. It checks to see whether the Element is text-only, or has non-text content. If it is text-only there is no indent/newline handling and it delegates to the correct text-type print method, otherwise it delegates to printContent.
    • printContent is called to output all lists of Content. It assumes that all whitespace indentation/newlines are appropriate before it is called, but it will ensure that padding is appropriate between the items in the list.

    Final Notes

    No methods actually write to the destination Writer except the write(...) methods. Thus, all other methods do their respective processing and delegate the actual destination output to the write(Writer, char) or write(Writer, String) methods.

    All Text-like content (printCDATA, printText, and printEntityRef) will ultimately be output through the the text* methods (and no other content).

    Since:
    JDOM2
    See Also:
    XMLOutputter2, XMLOutputProcessor
    • Constructor Detail

      • AbstractXMLOutputProcessor

        public AbstractXMLOutputProcessor()
    • Method Detail

      • process

        public void process​(Writer out,
                            Format format,
                            Document doc)
                     throws IOException
        Description copied from interface: XMLOutputProcessor
        This will print the Document to the given Writer.

        Warning: using your own Writer may cause the outputter's preferred character encoding to be ignored. If you use encodings other than UTF-8, we recommend using the method that takes an OutputStream instead.

        Specified by:
        process in interface XMLOutputProcessor
        Parameters:
        out - Writer to use.
        format - Format instance specifying output style
        doc - Document to format.
        Throws:
        IOException - if there's any problem writing.
      • process

        public void process​(Writer out,
                            Format format,
                            List<? extends Content> list)
                     throws IOException
        Description copied from interface: XMLOutputProcessor
        This will handle printing out a list of nodes. This can be useful for printing the content of an element that contains HTML, like "<description>JDOM is <b>fun>!</description>".
        Specified by:
        process in interface XMLOutputProcessor
        Parameters:
        out - Writer to use.
        format - Format instance specifying output style
        list - List of nodes.
        Throws:
        IOException - if there's any problem writing.
      • process

        public void process​(Writer out,
                            Format format,
                            Text text)
                     throws IOException
        Description copied from interface: XMLOutputProcessor
        Print out a Text node. Perfoms the necessary entity escaping and whitespace stripping.
        Specified by:
        process in interface XMLOutputProcessor
        Parameters:
        out - Writer to use.
        format - Format instance specifying output style
        text - Text to output.
        Throws:
        IOException - if there's any problem writing.
      • write

        protected void write​(Writer out,
                             String str)
                      throws IOException
        Print some string value to the output. Null values are ignored. This ignore-null property is used for a few tricks.
        Parameters:
        out - The Writer to write to.
        str - The String to write (can be null).
        Throws:
        IOException - if the out Writer fails.
      • write

        protected void write​(Writer out,
                             char c)
                      throws IOException
        Write a single character to the output Writer.
        Parameters:
        out - The Writer to write to.
        c - The char to write.
        Throws:
        IOException - if the Writer fails.
      • attributeEscapedEntitiesFilter

        protected void attributeEscapedEntitiesFilter​(Writer out,
                                                      FormatStack fstack,
                                                      String value)
                                               throws IOException
        This will take the three pre-defined entities in XML 1.0 ('<', '>', and '&' - used specifically in XML elements) as well as CR/NL and Quote characters which require escaping inside Attribute values and convert their character representation to the appropriate entity reference suitable for XML attribute content. Further, some special characters (e.g. characters that are not valid in the current encoding) are converted to escaped representations.

        Note: If FormatStack.getEscapeOutput() is false then no escaping will happen.

        Parameters:
        out - The destination Writer
        fstack - The FormatStack
        value - String Attribute value to escape.
        Throws:
        IOException - if the destination Writer fails.
        IllegalDataException - if an entity can not be escaped
      • textRaw

        protected void textRaw​(Writer out,
                               String str)
                        throws IOException
        Convenience method that simply passes the input str to write(Writer, String). This could be useful for subclasses to hook in to. All text-type output will come through this or the textRaw(Writer, char) method.
        Parameters:
        out - the destination writer.
        str - the String to write.
        Throws:
        IOException - if the Writer fails.
      • textRaw

        protected void textRaw​(Writer out,
                               char ch)
                        throws IOException
        Convenience method that simply passes the input char to write(Writer, char). This could be useful for subclasses to hook in to. All text-type output will come through this or the textRaw(Writer, String) method.
        Parameters:
        out - the destination Writer.
        ch - the char to write.
        Throws:
        IOException - if the Writer fails.
      • textEntityRef

        protected void textEntityRef​(Writer out,
                                     String name)
                              throws IOException
        Write an EntityRef to the destination.
        Parameters:
        out - the destination Writer.
        name - the EntityRef's name.
        Throws:
        IOException - if the Writer fails.
      • textCDATA

        protected void textCDATA​(Writer out,
                                 String text)
                          throws IOException
        Write a CDATA to the destination
        Parameters:
        out - the destination Writer
        text - the CDATA text
        Throws:
        IOException - if the Writer fails.
      • printDocument

        protected void printDocument​(Writer out,
                                     FormatStack fstack,
                                     NamespaceStack nstack,
                                     Document doc)
                              throws IOException
        This will handle printing of a Document.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        nstack - the NamespaceStack
        doc - Document to write.
        Throws:
        IOException - if the destination Writer fails
      • printDeclaration

        protected void printDeclaration​(Writer out,
                                        FormatStack fstack)
                                 throws IOException
        This will handle printing of the XML declaration. Assumes XML version 1.0 since we don't directly know.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        Throws:
        IOException - if the destination Writer fails
      • printDocType

        protected void printDocType​(Writer out,
                                    FormatStack fstack,
                                    DocType docType)
                             throws IOException
        This will handle printing of a DocType.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        docType - DocType to write.
        Throws:
        IOException - if the destination Writer fails
      • printComment

        protected void printComment​(Writer out,
                                    FormatStack fstack,
                                    Comment comment)
                             throws IOException
        This will handle printing of a Comment.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        comment - Comment to write.
        Throws:
        IOException - if the destination Writer fails
      • printEntityRef

        protected void printEntityRef​(Writer out,
                                      FormatStack fstack,
                                      EntityRef entity)
                               throws IOException
        This will handle printing of an EntityRef.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        entity - EntotyRef to write.
        Throws:
        IOException - if the destination Writer fails
      • printCDATA

        protected void printCDATA​(Writer out,
                                  FormatStack fstack,
                                  CDATA cdata)
                           throws IOException
        This will handle printing of a CDATA.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        cdata - CDATA to write.
        Throws:
        IOException - if the destination Writer fails
      • printText

        protected void printText​(Writer out,
                                 FormatStack fstack,
                                 Text text)
                          throws IOException
        This will handle printing of a Text.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        text - Text to write.
        Throws:
        IOException - if the destination Writer fails
      • printElement

        protected void printElement​(Writer out,
                                    FormatStack fstack,
                                    NamespaceStack nstack,
                                    Element element)
                             throws IOException
        This will handle printing of an Element.

        This method arranges for outputting the Element infrastructure including Namespace Declarations and Attributes.

        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        nstack - the NamespaceStack
        element - Element to write.
        Throws:
        IOException - if the destination Writer fails
      • printContent

        protected void printContent​(Writer out,
                                    FormatStack fstack,
                                    NamespaceStack nstack,
                                    Walker walker)
                             throws IOException
        This will handle printing of a List of Content.

        The list of Content is basically processed as one of three types of content

        1. Consecutive text-type (Text, CDATA, and EntityRef) content
        2. Stand-alone text-type content
        3. Non-text-type content.
        Although the code looks complex, the theory is conceptually simple:
        1. identify one of the three types (consecutive, stand-alone, non-text)
        2. do indent if any is specified.
        3. send the type to the respective print* handler (e.g. printCDATA(Writer, FormatStack, CDATA), or printComment(Writer, FormatStack, Comment),
        4. do a newline if one is specified.
        5. loop back to 1. until there's no more content to process.
        Parameters:
        out - Writer to use.
        fstack - the FormatStack
        nstack - the NamespaceStack
        walker - Walker of Content to write.
        Throws:
        IOException - if the destination Writer fails
      • printNamespace

        protected void printNamespace​(Writer out,
                                      FormatStack fstack,
                                      Namespace ns)
                               throws IOException
        This will handle printing of any needed Namespace declarations.
        Parameters:
        out - Writer to use.
        fstack - The current FormatStack
        ns - Namespace to print definition of
        Throws:
        IOException - if the output fails
      • printAttribute

        protected void printAttribute​(Writer out,
                                      FormatStack fstack,
                                      Attribute attribute)
                               throws IOException
        This will handle printing of an Attribute.
        Parameters:
        out - Writer to use.
        fstack - The current FormatStack
        attribute - Attribute to output
        Throws:
        IOException - if the output fails