/*
 * 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;

/**
 *  This interface represents an input source for data. 
 * <p> This interface allows an application to encapsulate information about 
 * an input source in a single object, which may include a public 
 * identifier, a system identifier, a byte stream (possibly with a specified 
 * encoding), a base URI, and/or a character stream. 
 * <p> The exact definitions of a byte stream and a character stream are 
 * binding dependent. 
 * <p> The application is expected to provide objects that implement this 
 * interface whenever such objects are needed. The application can either 
 * provide its own objects that implement this interface, or it can use the 
 * generic factory method <code>DOMImplementationLS.createLSInput()</code> 
 * to create objects that implement this interface. 
 * <p> The <code>LSParser</code> will use the <code>LSInput</code> object to 
 * determine how to read data. The <code>LSParser</code> will look at the 
 * different inputs specified in the <code>LSInput</code> in the following 
 * order to know which one to read from, the first one that is not null and 
 * not an empty string will be used: 
 * <ol>
 * <li> <code>LSInput.characterStream</code> 
 * </li>
 * <li> 
 * <code>LSInput.byteStream</code> 
 * </li>
 * <li> <code>LSInput.stringData</code> 
 * </li>
 * <li> 
 * <code>LSInput.systemId</code> 
 * </li>
 * <li> <code>LSInput.publicId</code> 
 * </li>
 * </ol> 
 * <p> If all inputs are null, the <code>LSParser</code> will report a 
 * <code>DOMError</code> with its <code>DOMError.type</code> set to 
 * <code>"no-input-specified"</code> and its <code>DOMError.severity</code> 
 * set to <code>DOMError.SEVERITY_FATAL_ERROR</code>. 
 * <p> <code>LSInput</code> objects belong to the application. The DOM 
 * implementation will never modify them (though it may make copies and 
 * modify the copies, if necessary). 
 * <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 LSInput {
    /**
     *  An attribute of a language and binding dependent type that represents 
     * a stream of 16-bit units. The application must encode the stream 
     * using UTF-16 (defined in [Unicode] and in [ISO/IEC 10646]). It is not a requirement to have an XML declaration when 
     * using character streams. If an XML declaration is present, the value 
     * of the encoding attribute will be ignored. 
     */
    public java.io.Reader getCharacterStream();
    /**
     *  An attribute of a language and binding dependent type that represents 
     * a stream of 16-bit units. The application must encode the stream 
     * using UTF-16 (defined in [Unicode] and in [ISO/IEC 10646]). It is not a requirement to have an XML declaration when 
     * using character streams. If an XML declaration is present, the value 
     * of the encoding attribute will be ignored. 
     */
    public void setCharacterStream(java.io.Reader characterStream);

    /**
     *  An attribute of a language and binding dependent type that represents 
     * a stream of bytes. 
     * <br> If the application knows the character encoding of the byte 
     * stream, it should set the encoding attribute. Setting the encoding in 
     * this way will override any encoding specified in an XML declaration 
     * in the data. 
     */
    public java.io.InputStream getByteStream();
    /**
     *  An attribute of a language and binding dependent type that represents 
     * a stream of bytes. 
     * <br> If the application knows the character encoding of the byte 
     * stream, it should set the encoding attribute. Setting the encoding in 
     * this way will override any encoding specified in an XML declaration 
     * in the data. 
     */
    public void setByteStream(java.io.InputStream byteStream);

    /**
     *  String data to parse. If provided, this will always be treated as a 
     * sequence of 16-bit units (UTF-16 encoded characters). It is not a 
     * requirement to have an XML declaration when using 
     * <code>stringData</code>. If an XML declaration is present, the value 
     * of the encoding attribute will be ignored. 
     */
    public String getStringData();
    /**
     *  String data to parse. If provided, this will always be treated as a 
     * sequence of 16-bit units (UTF-16 encoded characters). It is not a 
     * requirement to have an XML declaration when using 
     * <code>stringData</code>. If an XML declaration is present, the value 
     * of the encoding attribute will be ignored. 
     */
    public void setStringData(String stringData);

    /**
     *  The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], for this 
     * input source. The system identifier is optional if there is a byte 
     * stream, a character stream, or string data. It is still useful to 
     * provide one, since the application will use it to resolve any 
     * relative URIs and can include it in error messages and warnings. (The 
     * LSParser will only attempt to fetch the resource identified by the 
     * URI reference if there is no other input available in the input 
     * source.) 
     * <br> If the application knows the character encoding of the object 
     * pointed to by the system identifier, it can set the encoding using 
     * the <code>encoding</code> attribute. 
     * <br> If the specified system ID is a relative URI reference (see 
     * section 5 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the DOM 
     * implementation will attempt to resolve the relative URI with the 
     * <code>baseURI</code> as the base, if that fails, the behavior is 
     * implementation dependent. 
     */
    public String getSystemId();
    /**
     *  The system identifier, a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>], for this 
     * input source. The system identifier is optional if there is a byte 
     * stream, a character stream, or string data. It is still useful to 
     * provide one, since the application will use it to resolve any 
     * relative URIs and can include it in error messages and warnings. (The 
     * LSParser will only attempt to fetch the resource identified by the 
     * URI reference if there is no other input available in the input 
     * source.) 
     * <br> If the application knows the character encoding of the object 
     * pointed to by the system identifier, it can set the encoding using 
     * the <code>encoding</code> attribute. 
     * <br> If the specified system ID is a relative URI reference (see 
     * section 5 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the DOM 
     * implementation will attempt to resolve the relative URI with the 
     * <code>baseURI</code> as the base, if that fails, the behavior is 
     * implementation dependent. 
     */
    public void setSystemId(String systemId);

    /**
     *  The public identifier for this input source. This may be mapped to an 
     * input source using an implementation dependent mechanism (such as 
     * catalogues or other mappings). The public identifier, if specified, 
     * may also be reported as part of the location information when errors 
     * are reported. 
     */
    public String getPublicId();
    /**
     *  The public identifier for this input source. This may be mapped to an 
     * input source using an implementation dependent mechanism (such as 
     * catalogues or other mappings). The public identifier, if specified, 
     * may also be reported as part of the location information when errors 
     * are reported. 
     */
    public void setPublicId(String publicId);

    /**
     *  The base URI to be used (see section 5.1.4 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]) for 
     * resolving a relative <code>systemId</code> to an absolute URI. 
     * <br> If, when used, the base URI is itself a relative URI, an empty 
     * string, or null, the behavior is implementation dependent. 
     */
    public String getBaseURI();
    /**
     *  The base URI to be used (see section 5.1.4 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]) for 
     * resolving a relative <code>systemId</code> to an absolute URI. 
     * <br> If, when used, the base URI is itself a relative URI, an empty 
     * string, or null, the behavior is implementation dependent. 
     */
    public void setBaseURI(String baseURI);

    /**
     *  The character encoding, if known. The encoding must be a string 
     * acceptable for an XML encoding declaration ([<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] section 
     * 4.3.3 "Character Encoding in Entities"). 
     * <br> This attribute has no effect when the application provides a 
     * character stream or string data. For other sources of input, an 
     * encoding specified by means of this attribute will override any 
     * encoding specified in the XML declaration or the Text declaration, or 
     * an encoding obtained from a higher level protocol, such as HTTP [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>]. 
     */
    public String getEncoding();
    /**
     *  The character encoding, if known. The encoding must be a string 
     * acceptable for an XML encoding declaration ([<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>] section 
     * 4.3.3 "Character Encoding in Entities"). 
     * <br> This attribute has no effect when the application provides a 
     * character stream or string data. For other sources of input, an 
     * encoding specified by means of this attribute will override any 
     * encoding specified in the XML declaration or the Text declaration, or 
     * an encoding obtained from a higher level protocol, such as HTTP [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>]. 
     */
    public void setEncoding(String encoding);

    /**
     *  If set to true, assume that the input is certified (see section 2.13 
     * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]) when 
     * parsing [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. 
     */
    public boolean getCertifiedText();
    /**
     *  If set to true, assume that the input is certified (see section 2.13 
     * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]) when 
     * parsing [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>]. 
     */
    public void setCertifiedText(boolean certifiedText);

}
