/*
 * Copyright (c) 2004 World Wide Web Consortium,
 *
 * (Massachusetts Institute of Technology, European Research Consortium for
 * Informatics and Mathematics, Keio University). All Rights Reserved. This
 * work is distributed under the W3C(r) Software License [1] in the hope that
 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
 */

package org.w3c.dom.ls;

import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;

/**
 *  A <code>LSSerializer</code> provides an API for serializing (writing) a
 * DOM document out into XML. The XML data is written to a string or an
 * output stream. Any changes or fixups made during the serialization affect
 * only the serialized data. The <code>Document</code> object and its
 * children are never altered by the serialization operation.
 * <p> During serialization of XML data, namespace fixup is done as defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
 * , Appendix B. [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>DOM Level 2 Core</a>]
 *  allows empty strings as a real namespace URI. If the
 * <code>namespaceURI</code> of a <code>Node</code> is empty string, the
 * serialization will treat them as <code>null</code>, ignoring the prefix
 * if any.
 * <p> <code>LSSerializer</code> accepts any node type for serialization. For
 * nodes of type <code>Document</code> or <code>Entity</code>, well-formed
 * XML will be created when possible (well-formedness is guaranteed if the
 * document or entity comes from a parse operation and is unchanged since it
 * was created). The serialized output for these node types is either as a
 * XML document or an External XML Entity, respectively, and is acceptable
 * input for an XML parser. For all other types of nodes the serialized form
 * is implementation dependent.
 * <p>Within a <code>Document</code>, <code>DocumentFragment</code>, or
 * <code>Entity</code> being serialized, <code>Nodes</code> are processed as
 * follows
 * <ul>
 * <li> <code>Document</code> nodes are written, including the XML
 * declaration (unless the parameter "xml-declaration" is set to
 * <code>false</code>) and a DTD subset, if one exists in the DOM. Writing a
 * <code>Document</code> node serializes the entire document.
 * </li>
 * <li>
 * <code>Entity</code> nodes, when written directly by
 * <code>LSSerializer.write</code>, outputs the entity expansion but no
 * namespace fixup is done. The resulting output will be valid as an
 * external entity.
 * </li>
 * <li> If the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
 * entities</a>" is set to <code>true</code>, <code>EntityReference</code> nodes are
 * serialized as an entity reference of the form "
 * <code>&amp;entityName;</code>" in the output. Child nodes (the expansion)
 * of the entity reference are ignored. If the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
 * entities</a>" is set to <code>false</code>, only the children of the entity reference
 * are serialized. <code>EntityReference</code> nodes with no children (no
 * corresponding <code>Entity</code> node or the corresponding
 * <code>Entity</code> nodes have no children) are always serialized.
 * </li>
 * <li>
 * <code>CDATAsections</code> containing content characters that cannot be
 * represented in the specified output encoding are handled according to the
 * "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-split-cdata-sections'>
 * split-cdata-sections</a>" parameter.  If the parameter is set to <code>true</code>,
 * <code>CDATAsections</code> are split, and the unrepresentable characters
 * are serialized as numeric character references in ordinary content. The
 * exact position and number of splits is not specified.  If the parameter
 * is set to <code>false</code>, unrepresentable characters in a
 * <code>CDATAsection</code> are reported as
 * <code>"wf-invalid-character"</code> errors if the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-well-formed'>
 * well-formed</a>" is set to <code>true</code>. The error is not recoverable - there is no
 * mechanism for supplying alternative characters and continuing with the
 * serialization.
 * </li>
 * <li> <code>DocumentFragment</code> nodes are serialized by
 * serializing the children of the document fragment in the order they
 * appear in the document fragment.
 * </li>
 * <li> All other node types (Element, Text,
 * etc.) are serialized to their corresponding XML source form.
 * </li>
 * </ul>
 * <p ><b>Note:</b>  The serialization of a <code>Node</code> does not always
 * generate a well-formed XML document, i.e. a <code>LSParser</code> might
 * throw fatal errors when parsing the resulting serialization.
 * <p> Within the character data of a document (outside of markup), any
 * characters that cannot be represented directly are replaced with
 * character references. Occurrences of '&lt;' and '&amp;' are replaced by
 * the predefined entities &amp;lt; and &amp;amp;. The other predefined
 * entities (&amp;gt;, &amp;apos;, and &amp;quot;) might not be used, except
 * where needed (e.g. using &amp;gt; in cases such as ']]&gt;'). Any
 * characters that cannot be represented directly in the output character
 * encoding are serialized as numeric character references (and since
 * character encoding standards commonly use hexadecimal representations of
 * characters, using the hexadecimal representation when serializing
 * character references is encouraged).
 * <p> To allow attribute values to contain both single and double quotes, the
 * apostrophe or single-quote character (') may be represented as
 * "&amp;apos;", and the double-quote character (")  as "&amp;quot;". New
 * line characters and other characters that cannot be represented directly
 * in attribute values in the output character encoding are serialized as a
 * numeric character reference.
 * <p> Within markup, but outside of attributes, any occurrence of a character
 * that cannot be represented in the output character encoding is reported
 * as a <code>DOMError</code> fatal error. An example would be serializing
 * the element &lt;LaCa\u00f1ada/&gt; with <code>encoding="us-ascii"</code>.
 * This will result with a generation of a <code>DOMError</code>
 * "wf-invalid-character-in-node-name" (as proposed in "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-well-formed'>
 * well-formed</a>").
 * <p> When requested by setting the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-normalize-characters'>
 * normalize-characters</a>" on <code>LSSerializer</code> to true, character normalization is
 * performed according to the definition of <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully
 * normalized</a> characters included in appendix E of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] on all
 * data to be serialized, both markup and character data. The character
 * normalization process affects only the data as it is being written; it
 * does not alter the DOM's view of the document after serialization has
 * completed.
 * <p> Implementations are required to support the encodings "UTF-8",
 * "UTF-16", "UTF-16BE", and "UTF-16LE" to guarantee that data is
 * serializable in all encodings that are required to be supported by all
 * XML parsers. When the encoding is UTF-8, whether or not a byte order mark
 * is serialized, or if the output is big-endian or little-endian, is
 * implementation dependent. When the encoding is UTF-16, whether or not the
 * output is big-endian or little-endian is implementation dependent, but a
 * Byte Order Mark must be generated for non-character outputs, such as
 * <code>LSOutput.byteStream</code> or <code>LSOutput.systemId</code>. If
 * the Byte Order Mark is not generated, a "byte-order-mark-needed" warning
 * is reported. When the encoding is UTF-16LE or UTF-16BE, the output is
 * big-endian (UTF-16BE) or little-endian (UTF-16LE) and the Byte Order Mark
 * is not be generated. In all cases, the encoding declaration, if
 * generated, will correspond to the encoding used during the serialization
 * (e.g. <code>encoding="UTF-16"</code> will appear if UTF-16 was
 * requested).
 * <p> Namespaces are fixed up during serialization, the serialization process
 * will verify that namespace declarations, namespace prefixes and the
 * namespace URI associated with elements and attributes are consistent. If
 * inconsistencies are found, the serialized form of the document will be
 * altered to remove them. The method used for doing the namespace fixup
 * while serializing a document is the algorithm defined in Appendix B.1,
 * "Namespace normalization", of [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
 * .
 * <p> While serializing a document, the parameter "discard-default-content"
 * controls whether or not non-specified data is serialized.
 * <p> While serializing, errors and warnings are reported to the application
 * through the error handler (<code>LSSerializer.domConfig</code>'s "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
 * error-handler</a>" parameter). This specification does in no way try to define all possible
 * errors and warnings that can occur while serializing a DOM node, but some
 * common error and warning cases are defined. The types (
 * <code>DOMError.type</code>) of errors and warnings defined by this
 * specification are:
 * <dl>
 * <dt><code>"no-output-specified" [fatal]</code></dt>
 * <dd> Raised when
 * writing to a <code>LSOutput</code> if no output is specified in the
 * <code>LSOutput</code>. </dd>
 * <dt>
 * <code>"unbound-prefix-in-entity-reference" [fatal]</code> </dt>
 * <dd> Raised if the
 * configuration parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-namespaces'>
 * namespaces</a>" is set to <code>true</code> and an entity whose replacement text
 * contains unbound namespace prefixes is referenced in a location where
 * there are no bindings for the namespace prefixes. </dd>
 * <dt>
 * <code>"unsupported-encoding" [fatal]</code></dt>
 * <dd> Raised if an unsupported
 * encoding is encountered. </dd>
 * </dl>
 * <p> In addition to raising the defined errors and warnings, implementations
 * are expected to raise implementation specific errors and warnings for any
 * other error and warning cases such as IO errors (file not found,
 * permission denied,...) and so on.
 * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load
and Save Specification</a>.
 */
public interface LSSerializer {
    /**
     *  The <code>DOMConfiguration</code> object used by the
     * <code>LSSerializer</code> when serializing a DOM node.
     * <br> In addition to the parameters recognized by the <a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMConfiguration'>
     * DOMConfiguration</a> interface defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
     * , the <code>DOMConfiguration</code> objects for
     * <code>LSSerializer</code> adds, or modifies, the following
     * parameters:
     * <dl>
     * <dt><code>"canonical-form"</code></dt>
     * <dd>
     * <dl>
     * <dt><code>true</code></dt>
     * <dd>[<em>optional</em>] Writes the document according to the rules specified in [<a href='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'>Canonical XML</a>].
     * In addition to the behavior described in "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-canonical-form'>
     * canonical-form</a>" [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
     * , setting this parameter to <code>true</code> will set the parameters
     * "format-pretty-print", "discard-default-content", and "xml-declaration
     * ", to <code>false</code>. Setting one of those parameters to
     * <code>true</code> will set this parameter to <code>false</code>.
     * Serializing an XML 1.1 document when "canonical-form" is
     * <code>true</code> will generate a fatal error. </dd>
     * <dt><code>false</code></dt>
     * <dd>[<em>required</em>] (<em>default</em>) Do not canonicalize the output. </dd>
     * </dl></dd>
     * <dt><code>"discard-default-content"</code></dt>
     * <dd>
     * <dl>
     * <dt>
     * <code>true</code></dt>
     * <dd>[<em>required</em>] (<em>default</em>) Use the <code>Attr.specified</code> attribute to decide what attributes
     * should be discarded. Note that some implementations might use
     * whatever information available to the implementation (i.e. XML
     * schema, DTD, the <code>Attr.specified</code> attribute, and so on) to
     * determine what attributes and content to discard if this parameter is
     * set to <code>true</code>. </dd>
     * <dt><code>false</code></dt>
     * <dd>[<em>required</em>]Keep all attributes and all content.</dd>
     * </dl></dd>
     * <dt><code>"format-pretty-print"</code></dt>
     * <dd>
     * <dl>
     * <dt>
     * <code>true</code></dt>
     * <dd>[<em>optional</em>] Formatting the output by adding whitespace to produce a pretty-printed,
     * indented, human-readable form. The exact form of the transformations
     * is not specified by this specification. Pretty-printing changes the
     * content of the document and may affect the validity of the document,
     * validating implementations should preserve validity. </dd>
     * <dt>
     * <code>false</code></dt>
     * <dd>[<em>required</em>] (<em>default</em>) Don't pretty-print the result. </dd>
     * </dl></dd>
     * <dt>
     * <code>"ignore-unknown-character-denormalizations"</code> </dt>
     * <dd>
     * <dl>
     * <dt>
     * <code>true</code></dt>
     * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is
     * supported, a character is encountered for which the normalization
     * properties cannot be determined, then raise a
     * <code>"unknown-character-denormalization"</code> warning (instead of
     * raising an error, if this parameter is not set) and ignore any
     * possible denormalizations caused by these characters. </dd>
     * <dt>
     * <code>false</code></dt>
     * <dd>[<em>optional</em>] Report a fatal error if a character is encountered for which the
     * processor cannot determine the normalization properties. </dd>
     * </dl></dd>
     * <dt>
     * <code>"normalize-characters"</code></dt>
     * <dd> This parameter is equivalent to
     * the one defined by <code>DOMConfiguration</code> in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
     * . Unlike in the Core, the default value for this parameter is
     * <code>true</code>. While DOM implementations are not required to
     * support <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully
     * normalizing</a> the characters in the document according to appendix E of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], this
     * parameter must be activated by default if supported. </dd>
     * <dt>
     * <code>"xml-declaration"</code></dt>
     * <dd>
     * <dl>
     * <dt><code>true</code></dt>
     * <dd>[<em>required</em>] (<em>default</em>) If a <code>Document</code>, <code>Element</code>, or <code>Entity</code>
     *  node is serialized, the XML declaration, or text declaration, should
     * be included. The version (<code>Document.xmlVersion</code> if the
     * document is a Level 3 document and the version is non-null, otherwise
     * use the value "1.0"), and the output encoding (see
     * <code>LSSerializer.write</code> for details on how to find the output
     * encoding) are specified in the serialized XML declaration. </dd>
     * <dt>
     * <code>false</code></dt>
     * <dd>[<em>required</em>] Do not serialize the XML and text declarations. Report a
     * <code>"xml-declaration-needed"</code> warning if this will cause
     * problems (i.e. the serialized data is of an XML version other than [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], or an
     * encoding would be needed to be able to re-parse the serialized data). </dd>
     * </dl></dd>
     * </dl>
     */
    public DOMConfiguration getDomConfig();

    /**
     *  The end-of-line sequence of characters to be used in the XML being
     * written out. Any string is supported, but XML treats only a certain
     * set of characters sequence as end-of-line (See section 2.11,
     * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], if the
     * serialized content is XML 1.0 or section 2.11, "End-of-Line Handling"
     * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], if the
     * serialized content is XML 1.1). Using other character sequences than
     * the recommended ones can result in a document that is either not
     * serializable or not well-formed).
     * <br> On retrieval, the default value of this attribute is the
     * implementation specific default end-of-line sequence. DOM
     * implementations should choose the default to match the usual
     * convention for text files in the environment being used.
     * Implementations must choose a default sequence that matches one of
     * those allowed by XML 1.0 or XML 1.1, depending on the serialized
     * content. Setting this attribute to <code>null</code> will reset its
     * value to the default value.
     * <br>
     */
    public String getNewLine();
    /**
     *  The end-of-line sequence of characters to be used in the XML being
     * written out. Any string is supported, but XML treats only a certain
     * set of characters sequence as end-of-line (See section 2.11,
     * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], if the
     * serialized content is XML 1.0 or section 2.11, "End-of-Line Handling"
     * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], if the
     * serialized content is XML 1.1). Using other character sequences than
     * the recommended ones can result in a document that is either not
     * serializable or not well-formed).
     * <br> On retrieval, the default value of this attribute is the
     * implementation specific default end-of-line sequence. DOM
     * implementations should choose the default to match the usual
     * convention for text files in the environment being used.
     * Implementations must choose a default sequence that matches one of
     * those allowed by XML 1.0 or XML 1.1, depending on the serialized
     * content. Setting this attribute to <code>null</code> will reset its
     * value to the default value.
     * <br>
     */
    public void setNewLine(String newLine);

    /**
     *  When the application provides a filter, the serializer will call out
     * to the filter before serializing each Node. The filter implementation
     * can choose to remove the node from the stream or to terminate the
     * serialization early.
     * <br> The filter is invoked after the operations requested by the
     * <code>DOMConfiguration</code> parameters have been applied. For
     * example, CDATA sections won't be passed to the filter if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-cdata-sections'>
     * cdata-sections</a>" is set to <code>false</code>.
     *
     * @hide
     */
    public LSSerializerFilter getFilter();
    /**
     *  When the application provides a filter, the serializer will call out
     * to the filter before serializing each Node. The filter implementation
     * can choose to remove the node from the stream or to terminate the
     * serialization early.
     * <br> The filter is invoked after the operations requested by the
     * <code>DOMConfiguration</code> parameters have been applied. For
     * example, CDATA sections won't be passed to the filter if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-cdata-sections'>
     * cdata-sections</a>" is set to <code>false</code>.
     *
     * @hide
     */
    public void setFilter(LSSerializerFilter filter);

    /**
     *  Serialize the specified node as described above in the general
     * description of the <code>LSSerializer</code> interface. The output is
     * written to the supplied <code>LSOutput</code>.
     * <br> When writing to a <code>LSOutput</code>, the encoding is found by
     * looking at the encoding information that is reachable through the
     * <code>LSOutput</code> and the item to be written (or its owner
     * document) in this order:
     * <ol>
     * <li> <code>LSOutput.encoding</code>,
     * </li>
     * <li>
     * <code>Document.inputEncoding</code>,
     * </li>
     * <li>
     * <code>Document.xmlEncoding</code>.
     * </li>
     * </ol>
     * <br> If no encoding is reachable through the above properties, a
     * default encoding of "UTF-8" will be used. If the specified encoding
     * is not supported an "unsupported-encoding" fatal error is raised.
     * <br> If no output is specified in the <code>LSOutput</code>, a
     * "no-output-specified" fatal error is raised.
     * <br> The implementation is responsible of associating the appropriate
     * media type with the serialized data.
     * <br> When writing to a HTTP URI, a HTTP PUT is performed. When writing
     * to other types of URIs, the mechanism for writing the data to the URI
     * is implementation dependent.
     * @param nodeArg  The node to serialize.
     * @param destination The destination for the serialized DOM.
     * @return  Returns <code>true</code> if <code>node</code> was
     *   successfully serialized. Return <code>false</code> in case the
     *   normal processing stopped but the implementation kept serializing
     *   the document; the result of the serialization being implementation
     *   dependent then.
     * @exception LSException
     *    SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to
     *   serialize the node. DOM applications should attach a
     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
     *   error-handler</a>" if they wish to get details on the error.
     */
    public boolean write(Node nodeArg,
                         LSOutput destination)
                         throws LSException;

    /**
     *  A convenience method that acts as if <code>LSSerializer.write</code>
     * was called with a <code>LSOutput</code> with no encoding specified
     * and <code>LSOutput.systemId</code> set to the <code>uri</code>
     * argument.
     * @param nodeArg  The node to serialize.
     * @param uri The URI to write to.
     * @return  Returns <code>true</code> if <code>node</code> was
     *   successfully serialized. Return <code>false</code> in case the
     *   normal processing stopped but the implementation kept serializing
     *   the document; the result of the serialization being implementation
     *   dependent then.
     * @exception LSException
     *    SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to
     *   serialize the node. DOM applications should attach a
     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
     *   error-handler</a>" if they wish to get details on the error.
     */
    public boolean writeToURI(Node nodeArg,
                              String uri)
                              throws LSException;

    /**
     *  Serialize the specified node as described above in the general
     * description of the <code>LSSerializer</code> interface. The output is
     * written to a <code>DOMString</code> that is returned to the caller.
     * The encoding used is the encoding of the <code>DOMString</code> type,
     * i.e. UTF-16. Note that no Byte Order Mark is generated in a
     * <code>DOMString</code> object.
     * @param nodeArg  The node to serialize.
     * @return  Returns the serialized data.
     * @exception DOMException
     *    DOMSTRING_SIZE_ERR: Raised if the resulting string is too long to
     *   fit in a <code>DOMString</code>.
     * @exception LSException
     *    SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to
     *   serialize the node. DOM applications should attach a
     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
     *   error-handler</a>" if they wish to get details on the error.
     */
    public String writeToString(Node nodeArg)
                                throws DOMException, LSException;

}
