package org.xmlpull.v1;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

/**
 * Define an interface to serialization of XML Infoset.
 * This interface abstracts away if serialized XML is XML 1.0 compatible text or
 * other formats of XML 1.0 serializations (such as binary XML for example with WBXML).
 *
 * <p><b>PLEASE NOTE:</b> This interface will be part of XmlPull 1.2 API.
 * It is included as basis for discussion. It may change in any way.
 *
 * <p>Exceptions that may be thrown are: IOException or runtime exception
 * (more runtime exceptions can be thrown but are not declared and as such
 * have no semantics defined for this interface):
 * <ul>
 * <li><em>IllegalArgumentException</em> - for almost all methods to signal that
 *     argument is illegal
 * <li><em>IllegalStateException</em> - to signal that call has good arguments but
 *     is not expected here (violation of contract) and for features/properties
 *    when requesting setting unimplemented feature/property
 *    (UnsupportedOperationException would be better but it is not in MIDP)
 *  </ul>
 *
 * <p><b>NOTE:</b> writing  CDSECT, ENTITY_REF, IGNORABLE_WHITESPACE,
 *  PROCESSING_INSTRUCTION, COMMENT, and DOCDECL in some implementations
 * may not be supported (for example when serializing to WBXML).
 * In such case IllegalStateException will be thrown and it is recommended
 * to use an optional feature to signal that implementation is not
 * supporting this kind of output.
 */

public interface XmlSerializer {
    
    /**
     * Set feature identified by name (recommended to be URI for uniqueness).
     * Some well known optional features are defined in
     * <a href="http://www.xmlpull.org/v1/doc/features.html">
     * http://www.xmlpull.org/v1/doc/features.html</a>.
     *
     * If feature is not recognized or can not be set
     * then IllegalStateException MUST be thrown.
     *
     * @exception IllegalStateException If the feature is not supported or can not be set
     */
    void setFeature(String name,
                           boolean state)
        throws IllegalArgumentException, IllegalStateException;
    
    
    /**
     * Return the current value of the feature with given name.
     * <p><strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null
     *
     * @param name The name of feature to be retrieved.
     * @return The value of named feature.
     * @exception IllegalArgumentException if feature string is null
     */
    boolean getFeature(String name);
    
    
    /**
     * Set the value of a property.
     * (the property name is recommended to be URI for uniqueness).
     * Some well known optional properties are defined in
     * <a href="http://www.xmlpull.org/v1/doc/properties.html">
     * http://www.xmlpull.org/v1/doc/properties.html</a>.
     *
     * If property is not recognized or can not be set
     * then IllegalStateException MUST be thrown.
     *
     * @exception IllegalStateException if the property is not supported or can not be set
     */
    void setProperty(String name,
                            Object value)
        throws IllegalArgumentException, IllegalStateException;
    
    /**
     * Look up the value of a property.
     *
     * The property name is any fully-qualified URI. I
     * <p><strong>NOTE:</strong> unknown properties are <string>always</strong> returned as null
     *
     * @param name The name of property to be retrieved.
     * @return The value of named property.
     */
    Object getProperty(String name);
    
    /**
     * Set to use binary output stream with given encoding.
     */
    void setOutput (OutputStream os, String encoding)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Set the output to the given writer.
     * <p><b>WARNING</b> no information about encoding is available!
     */
    void setOutput (Writer writer)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Write &lt;&#63;xml declaration with encoding (if encoding not null)
     * and standalone flag (if standalone not null)
     * This method can only be called just after setOutput.
     */
    void startDocument (String encoding, Boolean standalone)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Finish writing. All unclosed start tags will be closed and output
     * will be flushed. After calling this method no more output can be
     * serialized until next call to setOutput()
     */
    void endDocument ()
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Binds the given prefix to the given namespace.
     * This call is valid for the next element including child elements.
     * The prefix and namespace MUST be always declared even if prefix
     * is not used in element (startTag() or attribute()) - for XML 1.0
     * it must result in declaring <code>xmlns:prefix='namespace'</code>
     * (or <code>xmlns:prefix="namespace"</code> depending what character is used
     * to quote attribute value).
     *
     * <p><b>NOTE:</b> this method MUST be called directly before startTag()
     *   and if anything but startTag() or setPrefix() is called next there will be exception.
     * <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
     *   and can not be redefined see:
     * <a href="http://www.w3.org/XML/xml-names-19990114-errata#NE05">Namespaces in XML Errata</a>.
     * <p><b>NOTE:</b> to set default namespace use as prefix empty string.
     *
     * @param prefix must be not null (or IllegalArgumentException is thrown)
     * @param namespace must be not null
     */
    void setPrefix (String prefix, String namespace)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Return namespace that corresponds to given prefix
     * If there is no prefix bound to this namespace return null
     * but if generatePrefix is false then return generated prefix.
     *
     * <p><b>NOTE:</b> if the prefix is empty string "" and default namespace is bound
     * to this prefix then empty string ("") is returned.
     *
     * <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
     *   will have values as defined
     * <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML specification</a>
     */
    String getPrefix (String namespace, boolean generatePrefix)
        throws IllegalArgumentException;
    
    /**
     * Returns the current depth of the element.
     * Outside the root element, the depth is 0. The
     * depth is incremented by 1 when startTag() is called.
     * The depth is decremented after the call to endTag()
     * event was observed.
     *
     * <pre>
     * &lt;!-- outside --&gt;     0
     * &lt;root&gt;               1
     *   sometext                 1
     *     &lt;foobar&gt;         2
     *     &lt;/foobar&gt;        2
     * &lt;/root&gt;              1
     * &lt;!-- outside --&gt;     0
     * </pre>
     */
    int getDepth();
    
    /**
     * Returns the namespace URI of the current element as set by startTag().
     *
     * <p><b>NOTE:</b> that means in particular that: <ul>
     * <li>if there was startTag("", ...) then getNamespace() returns ""
     * <li>if there was startTag(null, ...) then getNamespace() returns null
     * </ul>
     *
     * @return namespace set by startTag() that is currently in scope
     */
    String getNamespace ();
    
    /**
     * Returns the name of the current element as set by startTag().
     * It can only be null before first call to startTag()
     * or when last endTag() is called to close first startTag().
     *
     * @return namespace set by startTag() that is currently in scope
     */
    String getName();
    
    /**
     * Writes a start tag with the given namespace and name.
     * If there is no prefix defined for the given namespace,
     * a prefix will be defined automatically.
     * The explicit prefixes for namespaces can be established by calling setPrefix()
     * immediately before this method.
     * If namespace is null no namespace prefix is printed but just name.
     * If namespace is empty string then serializer will make sure that
     * default empty namespace is declared (in XML 1.0 xmlns='')
     * or throw IllegalStateException if default namespace is already bound
     * to non-empty string.
     */
    XmlSerializer startTag (String namespace, String name)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Write an attribute. Calls to attribute() MUST follow a call to
     * startTag() immediately. If there is no prefix defined for the
     * given namespace, a prefix will be defined automatically.
     * If namespace is null or empty string
     * no namespace prefix is printed but just name.
     */
    XmlSerializer attribute (String namespace, String name, String value)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Write end tag. Repetition of namespace and name is just for avoiding errors.
     * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
     *  very difficult to find...
     * If namespace is null no namespace prefix is printed but just name.
     * If namespace is empty string then serializer will make sure that
     * default empty namespace is declared (in XML 1.0 xmlns='').
     */
    XmlSerializer endTag (String namespace, String name)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    
    //    /**
    //     * Writes a start tag with the given namespace and name.
    //     * <br />If there is no prefix defined (prefix == null) for the given namespace,
    //     * a prefix will be defined automatically.
    //     * <br />If explicit prefixes is passed (prefix != null) then it will be used
    //      *and namespace declared if not already declared or
    //     * throw IllegalStateException the same prefix was already set on this
    //     * element (setPrefix()) and was bound to different namespace.
    //     * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
    //     * <br />If namespace is null then no namespace prefix is printed but just name.
    //     * <br />If namespace is empty string then serializer will make sure that
    //     * default empty namespace is declared (in XML 1.0 xmlns='')
    //     * or throw IllegalStateException if default namespace is already bound
    //     * to non-empty string.
    //     */
    //    XmlSerializer startTag (String prefix, String namespace, String name)
    //        throws IOException, IllegalArgumentException, IllegalStateException;
    //
    //    /**
    //     * Write an attribute. Calls to attribute() MUST follow a call to
    //     * startTag() immediately.
    //     * <br />If there is no prefix defined (prefix == null) for the given namespace,
    //     * a prefix will be defined automatically.
    //     * <br />If explicit prefixes is passed (prefix != null) then it will be used
    //     * and namespace declared if not already declared or
    //     * throw IllegalStateException the same prefix was already set on this
    //     * element (setPrefix()) and was bound to different namespace.
    //     * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
    //     * <br />If namespace is null then no namespace prefix is printed but just name.
    //     * <br />If namespace is empty string then serializer will make sure that
    //     * default empty namespace is declared (in XML 1.0 xmlns='')
    //     * or throw IllegalStateException if default namespace is already bound
    //     * to non-empty string.
    //     */
    //    XmlSerializer attribute (String prefix, String namespace, String name, String value)
    //        throws IOException, IllegalArgumentException, IllegalStateException;
    //
    //    /**
    //     * Write end tag. Repetition of namespace, prefix, and name is just for avoiding errors.
    //     * <br />If namespace or name arguments are different from corresponding startTag call
    //     * then IllegalArgumentException is thrown, if prefix argument is not null and is different
    //     * from corresponding starTag then IllegalArgumentException is thrown.
    //     * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
    //     * <br />If namespace is null then no namespace prefix is printed but just name.
    //     * <br />If namespace is empty string then serializer will make sure that
    //     * default empty namespace is declared (in XML 1.0 xmlns='').
    //     * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
    //     *  very difficult to find...</p>
    //     */
    // ALEK: This is really optional as prefix in end tag MUST correspond to start tag but good for error checking
    //    XmlSerializer endTag (String prefix, String namespace, String name)
    //        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Writes text, where special XML chars are escaped automatically
     */
    XmlSerializer text (String text)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Writes text, where special XML chars are escaped automatically
     */
    XmlSerializer text (char [] buf, int start, int len)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    void cdsect (String text)
        throws IOException, IllegalArgumentException, IllegalStateException;
    void entityRef (String text)  throws IOException,
        IllegalArgumentException, IllegalStateException;
    void processingInstruction (String text)
        throws IOException, IllegalArgumentException, IllegalStateException;
    void comment (String text)
        throws IOException, IllegalArgumentException, IllegalStateException;
    void docdecl (String text)
        throws IOException, IllegalArgumentException, IllegalStateException;
    void ignorableWhitespace (String text)
        throws IOException, IllegalArgumentException, IllegalStateException;
    
    /**
     * Write all pending output to the stream.
     * If method startTag() or attribute() was called then start tag is closed (final &gt;)
     * before flush() is called on underlying output stream.
     *
     * <p><b>NOTE:</b> if there is need to close start tag
     * (so no more attribute() calls are allowed) but without flushing output
     * call method text() with empty string (text("")).
     *
     */
    void flush ()
        throws IOException;
    
}
