/*
 * Copyright (c) 2003 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;

/**
 *  The <code>DOMConfiguration</code> interface represents the configuration 
 * of a document and maintains a table of recognized parameters. Using the 
 * configuration, it is possible to change 
 * <code>Document.normalizeDocument()</code> behavior, such as replacing the 
 * <code>CDATASection</code> nodes with <code>Text</code> nodes or 
 * specifying the type of the schema that must be used when the validation 
 * of the <code>Document</code> is requested. <code>DOMConfiguration</code> 
 * objects are also used in [<a href='http://www.w3.org/TR/2003/CR-DOM-Level-3-LS-20031107'>DOM Level 3 Load and Save</a>]
 *  in the <code>DOMParser</code> and <code>DOMSerializer</code> interfaces. 
 * <p> The parameter names used by the <code>DOMConfiguration</code> object 
 * are defined throughout the DOM Level 3 specifications. Names are 
 * case-insensitives. To avoid possible conflicts, as a convention, names 
 * referring to parameters defined outside the DOM specification should be 
 * made unique. Because parameters are exposed as properties in the , names 
 * are recommended to follow the section 5.16 Identifiers of [Unicode] with the addition of the character '-' (HYPHEN-MINUS) but it is not 
 * enforced by the DOM implementation. DOM Level 3 Core Implementations are 
 * required to recognize all parameters defined in this specification. Some 
 * parameter values may also be required to be supported by the 
 * implementation. Refer to the definition of the parameter to know if a 
 * value must be supported or not. 
 * <p ><b>Note:</b>  Parameters are similar to features and properties used in 
 * SAX2 [<a href='http://www.saxproject.org/'>SAX</a>]. 
 * <p> The following list of parameters defined in the DOM: 
 * <dl>
 * <dt>
 * <code>"canonical-form"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>optional</em>]Canonicalize the document according to the rules specified in [<a href='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'>Canonical XML</a>]. 
 * Note that this is limited to what can be represented in the DOM. In 
 * particular, there is no way to specify the order of the attributes in the 
 * DOM.This forces the following parameters to <code>false</code>: "entities
 * ", "normalize-characters", "cdata-sections".This forces the following 
 * parameters to <code>true</code>: "namespaces", "namespace-declarations", "
 * well-formed", "element-content-whitespace".Other parameters are not 
 * changed unless explicitly specified in the description of the parameters. 
 * In addition, the <code>DocumentType</code> node is removed from the tree 
 * if any and superfluous namespace declarations are removed from each 
 * element. Note that querying this parameter with <code>getParameter</code> 
 * cannot return <code>true</code> unless it has been set to 
 * <code>true</code> and the parameters described above are appropriately 
 * set.</dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Do not canonicalize the document.</dd>
 * </dl></dd>
 * <dt><code>"cdata-sections"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Keep <code>CDATASection</code> nodes in the document.</dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>]Transform <code>CDATASection</code> nodes in the document into 
 * <code>Text</code> nodes. The new <code>Text</code> node is then combined 
 * with any adjacent <code>Text</code> node.</dd>
 * </dl></dd>
 * <dt>
 * <code>"check-character-normalization"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>optional</em>] Check if the characters in the document are fully normalized according 
 * to the rules defined in [<a href='http://www.w3.org/TR/2003/WD-charmod-20030822/'>CharModel</a>] 
 * supplemented by the definitions of relevant constructs from <a href='http://www.w3.org/TR/2003/PR-xml11-20031105/#sec-normalization-checking'>
 * Section 2.13</a> of [<a href='http://www.w3.org/TR/2003/PR-xml11-20031105/'>XML 1.1</a>]. </dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Do not check if characters are normalized.</dd>
 * </dl></dd>
 * <dt><code>"comments"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Keep <code>Comment</code> nodes in the document.</dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>]Discard <code>Comment</code> nodes in the document.</dd>
 * </dl></dd>
 * <dt>
 * <code>"datatype-normalization"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>optional</em>] Exposed schema-normalized values in the tree. Since this parameter 
 * requires to have schema information, the "validate" parameter will also 
 * be set to <code>true</code>. Having this parameter activated when 
 * "validate" is <code>false</code> has no effect and no 
 * schema-normalization will happen. 
 * <p ><b>Note:</b>  Since the document contains the result of the XML 1.0 
 * processing, this parameter does not apply to attribute value 
 * normalization as defined in section 3.3.3 of [<a href='http://www.w3.org/TR/2000/REC-xml-20001006'>XML 1.0</a>] and is only 
 * meant for schema languages other than Document Type Definition (DTD). </dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>) Do not perform schema normalization on the tree. </dd>
 * </dl></dd>
 * <dt><code>"entities"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Keep <code>EntityReference</code> and <code>Entity</code> nodes in the 
 * document.</dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>] Remove all <code>EntityReference</code> and <code>Entity</code> nodes 
 * from the document, putting the entity expansions directly in their place. 
 * <code>Text</code> nodes are normalized, as defined in 
 * <code>Node.normalize</code>. Only <code>EntityReference</code> nodes to 
 * non-defined entities are kept in the document, with their associated 
 * <code>Entity</code> nodes if any. </dd>
 * </dl></dd>
 * <dt><code>"error-handler"</code></dt>
 * <dd>[<em>required</em>] Contains a <code>DOMErrorHandler</code> object. If an error is 
 * encountered in the document, the implementation will call back the 
 * <code>DOMErrorHandler</code> registered using this parameter. The 
 * implementation may provide a default <code>DOMErrorHandler</code> object. 
 *  When called, <code>DOMError.relatedData</code> will contain the closest 
 * node to where the error occurred. If the implementation is unable to 
 * determine the node where the error occurs, 
 * <code>DOMError.relatedData</code> will contain the <code>Document</code> 
 * node. Mutations to the document from within an error handler will result 
 * in implementation dependent behavior. </dd>
 * <dt><code>"infoset"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>]Keep in the document the information defined in the XML Information Set [<a href='http://www.w3.org/TR/2001/REC-xml-infoset-20011024/'>XML Information Set</a>]
 * .This forces the following parameters to <code>false</code>: "
 * validate-if-schema", "entities", "datatype-normalization", "cdata-sections
 * ".This forces the following parameters to <code>true</code>: "
 * namespace-declarations", "well-formed", "element-content-whitespace", "
 * comments", "namespaces".Other parameters are not changed unless 
 * explicitly specified in the description of the parameters. Note that 
 * querying this parameter with <code>getParameter</code> returns 
 * <code>true</code> only if the individual parameters specified above are 
 * appropriately set.</dd>
 * <dt><code>false</code></dt>
 * <dd>Setting <code>infoset</code> to 
 * <code>false</code> has no effect.</dd>
 * </dl></dd>
 * <dt><code>"namespaces"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>) Perform the namespace processing as defined in . </dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>optional</em>] Do not perform the namespace processing. </dd>
 * </dl></dd>
 * <dt>
 * <code>"namespace-declarations"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>) Include namespace declaration attributes, specified or defaulted from 
 * the schema, in the document. See also the sections "Declaring Namespaces" 
 * in [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>]
 *  and [<a href='http://www.w3.org/TR/2003/PR-xml-names11-20031105/'>XML Namespaces 1.1</a>]
 * .</dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>]Discard all namespace declaration attributes. The namespace prefixes (
 * <code>Node.prefix</code>) are retained even if this parameter is set to 
 * <code>false</code>.</dd>
 * </dl></dd>
 * <dt><code>"normalize-characters"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>optional</em>] Fully normalize the characters in the document according to the rules 
 * defined in [<a href='http://www.w3.org/TR/2003/WD-charmod-20030822/'>CharModel</a>] 
 * supplemented by the definitions of relevant constructs from <a href='http://www.w3.org/TR/2003/PR-xml11-20031105/#sec-normalization-checking'>
 * Section 2.13</a> of [<a href='http://www.w3.org/TR/2003/PR-xml11-20031105/'>XML 1.1</a>]. </dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Do not perform character normalization.</dd>
 * </dl></dd>
 * <dt><code>"schema-location"</code></dt>
 * <dd>[<em>optional</em>] Represent a <code>DOMString</code> object containing a list of URIs, 
 * separated by whitespaces (characters matching the <a href='http://www.w3.org/TR/2000/REC-xml-20001006#NT-S'>nonterminal 
 * production S</a> defined in section 2.3 [<a href='http://www.w3.org/TR/2000/REC-xml-20001006'>XML 1.0</a>]), that 
 * represents the schemas against which validation should occur, i.e. the 
 * current schema. The types of schemas referenced in this list must match 
 * the type specified with <code>schema-type</code>, otherwise the behavior 
 * of an implementation is undefined.  The schemas specified using this 
 * property take precedence to the schema information specified in the 
 * document itself. For namespace aware schema, if a schema specified using 
 * this property and a schema specified in the document instance (i.e. using 
 * the <code>schemaLocation</code> attribute) in a schema document (i.e. 
 * using schema <code>import</code> mechanisms) share the same 
 * <code>targetNamespace</code>, the schema specified by the user using this 
 * property will be used. If two schemas specified using this property share 
 * the same <code>targetNamespace</code> or have no namespace, the behavior 
 * is implementation dependent.  If no location has been provided, this 
 * parameter is <code>null</code>. 
 * <p ><b>Note:</b>  The <code>"schema-location"</code> parameter is ignored 
 * unless the "schema-type" parameter value is set. It is strongly 
 * recommended that <code>Document.documentURI</code> will be set so that an 
 * implementation can successfully resolve any external entities referenced. </dd>
 * <dt>
 * <code>"schema-type"</code></dt>
 * <dd>[<em>optional</em>] Represent a <code>DOMString</code> object containing an absolute URI 
 * and representing the type of the schema language used to validate a 
 * document against. Note that no lexical checking is done on the absolute 
 * URI.  If this parameter is not set, a default value may be provided by 
 * the implementation, based on the schema languages supported and on the 
 * schema language used at load time. If no value is provided, this 
 * parameter is <code>null</code>. 
 * <p ><b>Note:</b>  For XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>]
 * , applications must use the value 
 * <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD [<a href='http://www.w3.org/TR/2000/REC-xml-20001006'>XML 1.0</a>], 
 * applications must use the value 
 * <code>"http://www.w3.org/TR/REC-xml"</code>. Other schema languages are 
 * outside the scope of the W3C and therefore should recommend an absolute 
 * URI in order to use this method. </dd>
 * <dt><code>"split-cdata-sections"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Split CDATA sections containing the CDATA section termination marker 
 * ']]&gt;'. When a CDATA section is split a warning is issued with a 
 * <code>DOMError.type</code> equals to 
 * <code>"cdata-sections-splitted"</code> and 
 * <code>DOMError.relatedData</code> equals to the first 
 * <code>CDATASection</code> node in document order resulting from the split.</dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[<em>required</em>]Signal an error if a <code>CDATASection</code> contains an 
 * unrepresentable character.</dd>
 * </dl></dd>
 * <dt><code>"validate"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>optional</em>] Require the validation against a schema (i.e. XML schema, DTD, any 
 * other type or representation of schema) of the document as it is being 
 * normalized as defined by [<a href='http://www.w3.org/TR/2000/REC-xml-20001006'>XML 1.0</a>]. If 
 * validation errors are found, or no schema was found, the error handler is 
 * notified. Schema-normalized values will not be exposed according to the 
 * schema in used unless the parameter "datatype-normalization" is 
 * <code>true</code>.  This parameter will reevaluate: 
 * <ul>
 * <li> Attribute nodes with 
 * <code>Attr.specified</code> equals to <code>false</code>, as specified in 
 * the description of the <code>Attr</code> interface; 
 * </li>
 * <li> The value of the 
 * attribute <code>Text.isElementContentWhitespace</code> for all 
 * <code>Text</code> nodes; 
 * </li>
 * <li> The value of the attribute 
 * <code>Attr.isId</code> for all <code>Attr</code> nodes; 
 * </li>
 * <li> The attributes 
 * <code>Element.schemaTypeInfo</code> and <code>Attr.schemaTypeInfo</code>. 
 * </li>
 * </ul>
 * <p ><b>Note:</b>  "validate-if-schema" and "validate" are mutually 
 * exclusive, setting one of them to <code>true</code> will set the other 
 * one to <code>false</code>. Applications should also consider setting the 
 * parameter "well-formed" to <code>true</code>, which is the default for 
 * that option, when validating the document. </dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>) Do not accomplish schema processing, including the internal subset 
 * processing. Note that validation might still happen if "
 * "validate-if-schema" is <code>true</code>. </dd>
 * </dl></dd>
 * <dt>
 * <code>"validate-if-schema"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>optional</em>]Enable validation only if a declaration for the document element can be 
 * found in a schema (independently of where it is found, i.e. XML schema, 
 * DTD, or any other type or representation of schema). If validation is 
 * enabled, this parameter has the same behavior as the parameter "validate" 
 * set to <code>true</code>. 
 * <p ><b>Note:</b>  "validate-if-schema" and "validate" are mutually 
 * exclusive, setting one of them to <code>true</code> will set the other 
 * one to <code>false</code>. </dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>) No schema processing should be performed if the document has a schema, 
 * including internal subset processing. Note that validation must still 
 * happen if "validate" is <code>true</code>. </dd>
 * </dl></dd>
 * <dt><code>"well-formed"</code></dt>
 * <dd>
 * <dl>
 * <dt>
 * <code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>) Check if all nodes are XML well formed according to the XML version in 
 * use in <code>Document.xmlVersion</code>: 
 * <ul>
 * <li> check if the attribute 
 * <code>Node.nodeName</code> contains invalid characters according to its 
 * node type and generate a <code>DOMError</code> of type 
 * <code>"wf-invalid-character-in-node-name"</code>, with a 
 * <code>DOMError.SEVERITY_ERROR</code> severity, if necessary; 
 * </li>
 * <li> check if 
 * the text content inside <code>Attr</code>, <code>Element</code>, 
 * <code>Comment</code>, <code>Text</code>, <code>CDATASection</code> nodes 
 * for invalid characters and generate a <code>DOMError</code> of type 
 * <code>"wf-invalid-character"</code>, with a 
 * <code>DOMError.SEVERITY_ERROR</code> severity, if necessary; 
 * </li>
 * <li> check if 
 * the data inside <code>ProcessingInstruction</code> nodes for invalid 
 * characters and generate a <code>DOMError</code> of type 
 * <code>"wf-invalid-character"</code>, with a 
 * <code>DOMError.SEVERITY_ERROR</code> severity, if necessary; 
 * </li>
 * </ul></dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[<em>optional</em>] Do not check for XML well-formedness. </dd>
 * </dl></dd>
 * <dt>
 * <code>"element-content-whitespace"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[<em>required</em>] (<em>default</em>)Keep all whitespaces in the document.</dd>
 * <dt><code>false</code></dt>
 * <dd>[<em>optional</em>] Discard all <code>Text</code> nodes that contain whitespaces in element 
 * content, as described in <a href='http://www.w3.org/TR/2001/REC-xml-infoset-20011024#infoitem.character'>
 * [element content whitespace]</a>. The implementation is expected to use the attribute 
 * <code>Text.isElementContentWhitespace</code> to determine if a 
 * <code>Text</code> node should be discarded or not.</dd>
 * </dl></dd>
 * </dl>
 * <p> The resolution of the system identifiers associated with entities is 
 * done using <code>Document.documentURI</code>. However, when the feature 
 * "LS" defined in [<a href='http://www.w3.org/TR/2003/CR-DOM-Level-3-LS-20031107'>DOM Level 3 Load and Save</a>]
 *  is supported by the DOM implementation, the parameter 
 * "resource-resolver" can also be used on <code>DOMConfiguration</code> 
 * objects attached to <code>Document</code> nodes. If this parameter is 
 * set, <code>Document.normalizeDocument()</code> will invoke the resource 
 * resolver instead of using <code>Document.documentURI</code>. 
 * <p>See also the <a href='http://www.w3.org/TR/2003/CR-DOM-Level-3-Core-20031107'>Document Object Model (DOM) Level 3 Core Specification</a>.
 * @since DOM Level 3
 */
public interface DOMConfiguration {
    /**
     * Set the value of a parameter.
     * @param name The name of the parameter to set.
     * @param value  The new value or <code>null</code> if the user wishes to 
     *   unset the parameter. While the type of the value parameter is 
     *   defined as <code>DOMUserData</code>, the object type must match the 
     *   type defined by the definition of the parameter. For example, if 
     *   the parameter is "error-handler", the value must be of type 
     *   <code>DOMErrorHandler</code>. 
     * @exception DOMException
     *    NOT_FOUND_ERR: Raised when the parameter name is not recognized. 
     *   <br> NOT_SUPPORTED_ERR: Raised when the parameter name is recognized 
     *   but the requested value cannot be set. 
     *   <br> TYPE_MISMATCH_ERR: Raised if the value type for this parameter 
     *   name is incompatible with the expected value type. 
     */
    public void setParameter(String name, 
                             Object value)
                             throws DOMException;

    /**
     *  Return the value of a parameter if known. 
     * @param name  The name of the parameter. 
     * @return  The current object associated with the specified parameter or 
     *   <code>null</code> if no object has been associated or if the 
     *   parameter is not supported. 
     * @exception DOMException
     *    NOT_FOUND_ERR: Raised when the parameter name is not recognized. 
     */
    public Object getParameter(String name)
                               throws DOMException;

    /**
     * Check if setting a parameter to a specific value is supported.
     * @param name The name of the parameter to check.
     * @param value  An object. if <code>null</code>, the returned value is 
     *   <code>true</code>. 
     * @return  <code>true</code> if the parameter could be successfully set 
     *   to the specified value, or <code>false</code> if the parameter is 
     *   not recognized or the requested value is not supported. This does 
     *   not change the current value of the parameter itself. 
     */
    public boolean canSetParameter(String name, 
                                   Object value);

    /**
     *  The list of the parameters supported by this 
     * <code>DOMConfiguration</code> object and for which at least one value 
     * can be set by the application. Note that this list can also contain 
     * parameter names defined outside this specification. 
     */
    public DOMStringList getParameterNames();

}
