/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights 
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer. 
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:  
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must 
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written 
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache 
*    XMLBeans", nor may "Apache" appear in their name, without prior 
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems 
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans;

import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLStreamException;

import org.w3c.dom.Node;

import java.io.InputStream;
import java.io.File;
import java.io.Reader;
import java.io.IOException;

/**
 * Corresponds to the XML Schema
 * <a target="_blank" href="http://www.w3.org/TR/xmlschema-1/#key-urType">xs:anyType</a>,
 * the base type for all XML Beans.
 * <p>
 * Since all XML Schema types are translated into corresponding XML Bean
 * classes, and all Schema type derivation corresponds to Java class
 * inheritance, the fact that all Schema types derive from xs:anyType means
 * that all XML Bean classes derive from XmlObject.
 * <p>
 * On this base class you will find a number of common facilities that
 * all XML Bean classes provide:
 * <p>
 * <ul>
 * <li>Every XML Bean class has an inner Factory class for creating and parsing
 *     instances, including XmlObject. Use {@link XmlObject.Factory} itself
 *     to produce untyped XML trees or XML trees that implement specific
 *     subtypes of XmlObject depending on a recognized root document element.
 *     If you depend on the automatic type inference, you will want to understand
 *     the type inference issues described below.
 * <li>To write out an accurate XML file for the XML tree under this
 *     XmlObject, use one of the {@link #save} methods,
 *     or {@link #newInputStream} or {@link #newReader}.
 *     Use {@link #toString} to produce a pretty-printed representation of the
 *     XML subtree under this XML Object.  If you save interior portions of
 *     an XML document, you will want to understand the inner contents
 *     versus outer container issues described below.
 * <li>It is also simple to copy an XmlObject instance to or from a standard
 *     DOM tree or SAX stream.  Use {@link XmlObject.Factory#parse(Node)},
 *     for example, to load from DOM; use {@link XmlObject.Factory#newXmlSaxHandler}
 *     to load from SAX; use {@link #newDomNode()} to save to DOM; and use 
 *     {@link #save(org.xml.sax.ContentHandler, org.xml.sax.ext.LexicalHandler)}
 *     to save to SAX.
 * <li>Use {@link #validate} to validate the subtree of XML under this
 *     XML Object.  If you wish to get information about the location
 *     and reason for validation errors, see {@link XmlOptions#setErrorListener},
 *     and use {@link #validate(XmlOptions)}.
 * <li>Use {@link #newCursor} to access the full XML infoset, for example,
 *     if you need to determine interleaved element order or manipulate
 *     annotations, comments, or mixed content.  See {@link XmlCursor}.
 * <li>Use {@link #selectPath} to find other XmlObjects in the subtree underneath
 *     this XmlObject using relative XPaths.  (In selectPath, "." indicates
 *     the current element or attribute.)
 * </ul>
 * <p>
 * Type inference.  When using {@link XmlObject.Factory} to parse XML documents,
 * the actual document type is not {@link XmlObject#type} itself, but a subtype
 * based on the contents of the parsed document.  If the parsed document
 * contains a recognized root document element, then the actual type of the
 * loaded instance will be the matching Document type.  For example:
 * <pre>
 * XmlObject xobj = XmlObject.Factory.parse(myDocument);
 * if (xobj instanceof MyOrderDocument) // starts w/ &lt;my-order&gt;
 * {
 *     MyOrderDocument mydoc = (MyOrderDocument)xobj;
 *     if (!xobj.validate())
 *         System.out.println("Not a valid my-order document");
 * }
 * else
 * {
 *     System.out.println("Not a my-order document");
 * }
 * </pre>
 * Every XML Bean class has its own inner Factory class,
 * so if you actually know exactly which XML Bean document type
 * you want to load as in the example above, you should use the
 * the specific XML Bean Factory class instead. For example:
 * <pre>
 * MyOrderDocument mydoc = MyOrderDocument.Factory.parse(myDocument);
 * </pre>
 * The code above will throw an exception if the parsed document
 * does not begin with the proper (my-order) element.
 * <p>
 * Inner versus outer.  An XmlObject represents the
 * <em>contents</em> of an element or attribute, <em>not</em> the element
 * or attribute itself.  So when you validate or save an XmlObject, you
 * are validating or saving its contents, not its container.  For example,
 * if the XmlObject represents the contents of an element which happens
 * to itself be in the wrong order relative to its siblings, validate will
 * not complain about the misplacement of the element itself.  On the other hand, if
 * elements <em>within</em> the XmlObject are in the wrong order, validate
 * will complain.  Similarly, when saving the contents of an interior
 * XmlObject, it is the contents of an element, not the element itself,
 * which is saved by default.
 * <p>
 * Reading and writing fragments. When reading or writing the contents of a
 * whole XML document, the standard XML reprentation for a document is used.
 * However, there is no standard concrete XML representation for "just the
 * contents" of an interior element or attribute. So when one is needed,
 * the tag &lt;xml-fragment&gt; is used to wrap the contents.  This tag is used
 * can also be used to load just the contents for an XmlObject document fragment
 * of arbitrary type. If you wish to save out the XmlObject's container element
 * along with its contents, use {@link XmlOptions#setSaveOuter}.
 * <p>
 * Implementing XmlObject.  The XMLBeans library does not support arbitrary
 * implementations of XmlObject - in almost all cases, you should only use
 * the implementations of XmlObject provided by the XMLBeans compiler itself.
 * If you need to implement XmlObject yourself, you should subclass
 * FilterXmlObject in order to delegate to another underlying XmlObject
 * implementation. This technique will allow you to use your code unchanged
 * with future versions of XMLBeans that add additional methods on XmlObject. 
 */ 
public interface XmlObject extends XmlTokenSource
{
    /** The constant {@link SchemaType} object representing this schema type. */
    public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_anyType");

    /**
     * The schema type for this instance. This is a permanent,
     * unchanging property of the instance.
     */
    SchemaType schemaType();

    /**
     * Returns true if the contents of this object are valid
     * accoring to schemaType().
     * <p>
     * Does a deep validation of the entire subtree under the
     * object, but does not validate the parents or siblings
     * of the object if the object is in the interior of an xml
     * tree.
     */
    boolean validate();
    
    /**
     * <p>Just like validate(), but with options.</p>
     * <p>If you wish to collect error messages and locations while validating,
     * use the {@link XmlOptions#setErrorListener} method. With that method,
     * you can specify an object in which to store messages related to validation.
     * The following is a simple example.</p>
     * 
     * <pre>
     * // Create an XmlOptions instance and set the error listener.
     * XmlOptions validateOptions = new XmlOptions();
     * ArrayList errorList = new ArrayList();
     * validateOptions.setErrorListener(errorList);
     * 
     * // Validate the XML.
     * boolean isValid = newEmp.validate(validateOptions);
     * 
     * // If the XML isn't valid, loop through the listener's contents,
     * // printing contained messages.
     * if (!isValid)
     * {
     *      for (int i = 0; i < errorList.size(); i++)
     *      {
     *          XmlError error = (XmlError)errorList.get(i);
     *          
     *          System.out.println("\n");
     *          System.out.println("Message: " + error.getMessage() + "\n");
     *          System.out.println("Location of invalid XML: " + 
     *              error.getCursorLocation().xmlText() + "\n");
     *      }
     * }
     * </pre>
     * 
     * @param options An object that implements the {@link java.util.Collection 
     * Collection} interface.
     */
    boolean validate(XmlOptions options);

    /**
     * Selects a path.  Path can be a string or precompiled path String.
     * <p>
     * The path must be a relative path, where "." represents the
     * element or attribute containg this XmlObject, and it must select
     * only other elements or attributes.  If a non-element or non-attribute
     * is selected, an unchecked exception is thrown.
     * <p>
     * The array that is returned contains all the selected
     * XmlObjects, within the same document, listed in document
     * order.  The actual array type of the result is inferred
     * from the closest common base type of selected results.
     * <p>
     * Here is an example of usage.  Suppose we have a global
     * element definition for "owner" whose type is "person":
     * <pre>
     *   &lt;schema targetNamespace="http://openuri.org/sample">
     *      &lt;element name="owner" type="person"/>
     *      &lt;complexType name="person">
     *         [...]
     *      &lt;/complexType>
     *   &lt;/schema>
     * </pre>
     * and suppose "owner" tags can be scattered throughout the
     * document.  Then we can write the following code to find
     * them all:
     * <pre>
     * import org.openuri.sample.Person;
     * import org.apache.xmlbeans.*;
     * [...]
     *   XmlObject xobj = XmlObject.Factory.parse(myFile);
     *   Person[] results;
     *   results = (Person[])xobj.selectPath(
     *      "declare namespace s='http://www.openuri.org/sample' " +
     *      ".//s:owner");
     * </pre>
     * Notice the way in which namespace declarations are done in XPath 2.0.
     * Since XPath can only navigate within an XML document - it cannot
     * construct new XML - the resulting XmlObjects all reside in
     * the same XML document as this XmlObject itself.
     */
    XmlObject[] selectPath ( String path );

    /**
     * Selects a path, applying options.
     * 
     * @see #selectPath(String)
     */
    XmlObject[] selectPath ( String path, XmlOptions options );
    

    /**
     * Executes a query.  Query can be a string or precompiled query String.
     * <p>
     * An XQuery is very similar to an XPath, except that it also permits
     * construction of new XML.  As a result, the XmlObjects that are
     * returned from execQuery are in newly created documents, separate
     * from the XmlObject on which the query is executed.
     * <p>
     * Syntax and usage is otherwise similar to selectPath.
     * <p>
     * @see #selectPath(String)
     */
    XmlObject[] execQuery ( String query );

    /**
     * Executes a query with options.
     * 
     * Use the <em>options</em> parameter to specify the following:</p>
     * 
     * <table>
     * <tr><th>To specify this</th><th>Use this method</th></tr>
     * <tr>
     *  <td>The document type for the root element.</td>
     *  <td>{@link XmlOptions#setDocumentType}</td>
     * </tr>
     * <tr>
     *  <td>To replace the document element with the specified QName when constructing the
     *  resulting document.</td>
     *  <td>{@link XmlOptions#setLoadReplaceDocumentElement}</td>
     * </tr>
     * <tr>
     *  <td>To strip all insignificant whitespace when constructing a document.</td>
     *  <td>{@link XmlOptions#setLoadStripWhitespace}</td>
     * </tr>
     * <tr>
     *  <td>To strip all comments when constructing a document.</td>
     *  <td>{@link XmlOptions#setLoadStripComments}</td>
     * </tr>
     * <tr>
     *  <td>To strip all processing instructions when constructing a document.</td>
     *  <td>{@link XmlOptions#setLoadStripProcinsts}</td>
     * </tr>
     * <tr>
     *  <td>A map of namespace URI substitutions to use when constructing a document.</td>
     *  <td>{@link XmlOptions#setLoadSubstituteNamespaces}</td>
     * </tr>
     * <tr>
     *  <td>Additional namespace mappings to be added when constructing a document.</td>
     *  <td>{@link XmlOptions#setLoadAdditionalNamespaces}</td>
     * </tr>
     * <tr>
     *  <td>To trim the underlying XML text buffer immediately after constructing 
     *  a document, resulting in a smaller memory footprint.</td>
     *  <td>{@link XmlOptions#setLoadTrimTextBuffer}</td>
     * </tr>
     * <tr>
     *  <td>Whether value facets should be checked as they are set.</td>
     *  <td>{@link XmlOptions#setValidateOnSet}</td>
     * </tr>
     * </table> 
     * 
     * @param query The XQuery expression.
     * @param options Options as described.
     * 
     * @see #execQuery(String)
     */
    XmlObject[] execQuery ( String query, XmlOptions options );
    

    /**
     * Changes the schema type associated with this data and
     * returns a new XmlObject instance whose schemaType is the
     * new type.
     * <p>
     * Returns null if the type change is not allowed. Certain
     * type changes may be prohibited on the interior of an xml
     * tree due to schema type system constraints (that is, due
     * to a parent container within which the newly specified
     * type is not permissible), but there are no constraints
     * at the roottype changes are never
     * prohibited at the root of an xml tree.
     * <p>
     * If the type change is allowed, then the new XmlObject should
     * be used rather than the old one. The old XmlObject instance and
     * any other XmlObject instances in the subtree are permanently
     * invalidated and should not be used. (They will return
     * InvalidStateException if you try to use them.)
     *
     * If a type change is done on the interior of an Xml
     * tree, then xsi:type attributes are updated as needed.
     */
    XmlObject changeType(SchemaType newType);


    /**
     * True if the value is nil. Note that in order to be nil,
     * the value must be in an element, and the element containing
     * the value must be marked as nillable in the schema.
     */
    boolean isNil();

    /**
     * Sets the value to nil. The element containing the value must
     * be marked as nillable in the schema.
     */
    void setNil();


    /**
     * Returns an XML string for this XML object.
     * <p>
     * The string is pretty-printed.  If you want a non-pretty-printed
     * string, or if you want to control options precisely, use the
     * xmlText() methods.
     * <p>
     * Note that when producing XML any object other than very root of the
     * document, then you are guaranteed to be looking at only a fragment
     * of XML, i.e., just the contents of an element or attribute, and
     * and we will produce a string that starts with an <code>&lt;xml-fragment&gt;</code> tag.
     * The XmlOptions.setSaveOuter() option on xmlText can be used to produce
     * the actual element name above the object if you wish.
     */
    String toString();

    /**
     * True if the value is an immutable value. Immutable values do not
     * have a position in a tree; rather, they are stand-alone simple type
     * values. If the object is immutable, the equals() methods tests for
     * value equality, and the object can be used as the key for a hash.
     */
    boolean isImmutable();

    /**
     * Set the value/type of this XmlObject to be a copy of the source
     * XmlObject.  Because the type of the source may be different than this
     * target, this XmlObject may become defunct.  In this case the new
     * XmlObject is returned.  If no type change happens, the same this will be
     * returned.
     */
    XmlObject set(XmlObject srcObj);
    
    /**
     * Returns a deep copy of this XmlObject.  The returned object has the
     * same type as the current object, and has all the content of
     * the XML document underneath the current object.  Note that
     * any parts of the XML document above or outside this XmlObject are
     * not copied.
     */
    XmlObject copy();

    /**
     * True if the xml values are equal. Two different objects
     * (which are distinguished by equals(obj) == false) may of
     * course have equal values (valueEquals(obj) == true).
     * <p>
     * Usually this method can be treated as an ordinary equvalence
     * relation, but actually it is not is not transitive.
     * Here is a precise specification:
     * <p>
     * There are two categories of XML object: objects with a known
     * instance type, and objects whose only known type is one of the
     * ur-types (either AnyType or AnySimpleType). The first category
     * is compared in terms of logical value spaces, and the second
     * category is compared lexically.
     * <p>
     * Within each of these two categories, valueEquals is a well-behaved
     * equivalence relation. However, when comparing an object of known
     * type with an object with ur-type, the comparison is done by attempting
     * to convert the lexical form of the ur-typed object into the other
     * type, and then comparing the results. Ur-typed objects are therefore
     * treated as lexical wildcards and may be equal to objects in different
     * value spaces, even though the objects in different value spaces are
     * not equal to each other.
     * <p>
     * For example, the anySimpleType value "1" will compare as an
     * equalValue to the string "1", the float value "1.0", the double
     * value "1.0", the decimal "1", and the GYear "1", even though
     * all these objects will compare unequal to each other since they
     * lie in different value spaces.
     */
    boolean valueEquals(XmlObject obj);

    int valueHashCode();

    /**
     * Impelements the Comparable interface by comparing two simple
     * xml values based on their standard XML schema ordering.
     * Throws a ClassCastException if no standard ordering applies,
     * or if the two values are incomparable within a partial order.
     */
    int compareTo(Object obj);

    /**
     * This comparison method is similar to compareTo, but rather
     * than throwing a ClassCastException when two values are incomparable,
     * it returns the number 2. The result codes are -1 if this object
     * is less than obj, 1 if this object is greater than obj, zero if
     * the objects are equal, and 2 if the objects are incomparable.
     */
    int compareValue(XmlObject obj);
    
    /** LESS_THAN is -1. See {@link #compareValue}. */
    static final int LESS_THAN = -1;
    /** EQUAL is 0. See {@link #compareValue}. */
    static final int EQUAL = 0;
    /** GREATER_THAN is 1. See {@link #compareValue}. */
    static final int GREATER_THAN = 1;
    /** NOT_EQUAL is 2. See {@link #compareValue}. */
    static final int NOT_EQUAL = 2;

    /**
     * Static factory class for creating new instances.  Note that if
     * a type can be inferred from the XML being loaded (for example,
     * by recognizing the document element QName), then the instance
     * returned by a factory will have the inferred type.  Otherwise
     * the Factory will returned an untyped document.
     */
    public static final class Factory
    {
        /**
         * Creates a new, completely empty instance.
         */ 
        public static XmlObject newInstance ( ) {
          return XmlBeans.getContextTypeLoader().newInstance( null, null ); }
        
        /**
         * <p>Creates a new, completely empty instance, specifying options
         * for the root element's document type and/or whether to validate
         * value facets as they are set.</p>
         * 
         * Use the <em>options</em> parameter to specify the following:</p>
         * 
         * <table>
         * <tr><th>To specify this</th><th>Use this method</th></tr>
         * <tr>
         *  <td>The document type for the root element.</td>
         *  <td>{@link XmlOptions#setDocumentType}</td>
         * </tr>
         * <tr>
         *  <td>Whether value facets should be checked as they are set.</td>
         *  <td>{@link XmlOptions#setValidateOnSet}</td>
         * </tr>
         * </table> 
         * 
         * @param options Options specifying root document type and/or value facet 
         * checking.
         * @return A new, empty instance of XmlObject.</li>
         */ 
        public static XmlObject newInstance ( XmlOptions options ) {
          return XmlBeans.getContextTypeLoader().newInstance( null, options ); }
        
        /**
         * Creates a new immutable value.
         */ 
        /** Creates an immutable {@link XmlObject} value */
        public static XmlObject newValue ( Object obj ) {
          return type.newValue( obj ); }
        
        /**
         * Parses the given {@link String} as XML.
         */ 
        public static XmlObject parse ( String s ) throws XmlException {
          return XmlBeans.getContextTypeLoader().parse( s, null, null ); }
        
        /**
         * Parses the given {@link String} as XML.
         * 
         * Use the <em>options</em> parameter to specify the following:</p>
         * 
         * <table>
         * <tr><th>To specify this</th><th>Use this method</th></tr>
         * <tr>
         *  <td>The document type for the root element.</td>
         *  <td>{@link XmlOptions#setDocumentType}</td>
         * </tr>
         * <tr>
         *  <td>To place line number annotations in the store when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadLineNumbers}</td>
         * </tr>
         * <tr>
         *  <td>To replace the document element with the specified QName when parsing.</td>
         *  <td>{@link XmlOptions#setLoadReplaceDocumentElement}</td>
         * </tr>
         * <tr>
         *  <td>To strip all insignificant whitespace when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadStripWhitespace}</td>
         * </tr>
         * <tr>
         *  <td>To strip all comments when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadStripComments}</td>
         * </tr>
         * <tr>
         *  <td>To strip all processing instructions when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadStripProcinsts}</td>
         * </tr>
         * <tr>
         *  <td>A map of namespace URI substitutions to use when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadSubstituteNamespaces}</td>
         * </tr>
         * <tr>
         *  <td>Additional namespace mappings to be added when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadAdditionalNamespaces}</td>
         * </tr>
         * <tr>
         *  <td>To trim the underlying XML text buffer immediately after parsing 
         *  a document, resulting in a smaller memory footprint.</td>
         *  <td>{@link XmlOptions#setLoadTrimTextBuffer}</td>
         * </tr>
         * </table> 
         * 
         * @param s The string to parse.
         * @param options Options as specified.
         * @return A new instance containing the specified XML.
         */ 
        public static XmlObject parse ( String s, XmlOptions options ) throws XmlException {
          return XmlBeans.getContextTypeLoader().parse( s, null, options ); }
        
        /**
         * Parses the given {@link File} as XML.
         */ 
        public static XmlObject parse ( File f ) throws XmlException, IOException {
          return XmlBeans.getContextTypeLoader().parse( f, null, null ); }

        /**
         * Parses the given {@link File} as XML.
         */ 
        public static XmlObject parse ( File f, XmlOptions options ) throws XmlException, IOException {
          return XmlBeans.getContextTypeLoader().parse( f, null, options ); }
        
        /**
         * Downloads the given {@link java.net.URL} as XML.
         */ 
        public static XmlObject parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return XmlBeans.getContextTypeLoader().parse( u, null, null ); }

        /**
         * Downloads the given {@link java.net.URL} as XML.
         */ 
        public static XmlObject parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return XmlBeans.getContextTypeLoader().parse( u, null, options ); }

        /**
         * Decodes and parses the given {@link InputStream} as XML.
         */ 
        public static XmlObject parse ( InputStream is ) throws XmlException, IOException {
          return XmlBeans.getContextTypeLoader().parse( is, null, null ); }
        
        /**
         * Decodes and parses the given {@link InputStream} as XML.
         * 
         * Use the <em>options</em> parameter to specify the following:</p>
         * 
         * <table>
         * <tr><th>To specify this</th><th>Use this method</th></tr>
         * <tr>
         *  <td>The character encoding to use when parsing or writing a document.</td>
         *  <td>{@link XmlOptions#setCharacterEncoding}</td>
         * </tr>
         * <tr>
         *  <td>The document type for the root element.</td>
         *  <td>{@link XmlOptions#setDocumentType}</td>
         * </tr>
         * <tr>
         *  <td>Place line number annotations in the store when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadLineNumbers}</td>
         * </tr>
         * <tr>
         *  <td>Replace the document element with the specified QName when parsing.</td>
         *  <td>{@link XmlOptions#setLoadReplaceDocumentElement}</td>
         * </tr>
         * <tr>
         *  <td>Strip all insignificant whitespace when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadStripWhitespace}</td>
         * </tr>
         * <tr>
         *  <td>Strip all comments when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadStripComments}</td>
         * </tr>
         * <tr>
         *  <td>Strip all processing instructions when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadStripProcinsts}</td>
         * </tr>
         * <tr>
         *  <td>Set a map of namespace URI substitutions to use when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadSubstituteNamespaces}</td>
         * </tr>
         * <tr>
         *  <td>Set additional namespace mappings to be added when parsing a document.</td>
         *  <td>{@link XmlOptions#setLoadAdditionalNamespaces}</td>
         * </tr>
         * <tr>
         *  <td>Trim the underlying XML text buffer immediately after parsing 
         *  a document, resulting in a smaller memory footprint.</td>
         *  <td>{@link XmlOptions#setLoadTrimTextBuffer}</td>
         * </tr>
         * </table> 
         */ 
        public static XmlObject parse ( InputStream is, XmlOptions options ) throws XmlException, IOException {
          return XmlBeans.getContextTypeLoader().parse( is, null, options ); }
        
        /**
         * Parses the given {@link Reader} as XML.
         */ 
        public static XmlObject parse ( Reader r ) throws XmlException, IOException {
          return XmlBeans.getContextTypeLoader().parse( r, null, null ); }
        
        /**
         * Parses the given {@link Reader} as XML.
         */ 
        public static XmlObject parse ( Reader r, XmlOptions options ) throws XmlException, IOException {
          return XmlBeans.getContextTypeLoader().parse( r, null, options ); }
        
        /**
         * Converts the given DOM {@link Node} into an XmlObject.
         */ 
        public static XmlObject parse ( Node node ) throws XmlException {
          return XmlBeans.getContextTypeLoader().parse( node, null, null ); }
        
        /**
         * Converts the given DOM {@link Node} into an XmlObject.
         */ 
        public static XmlObject parse ( Node node, XmlOptions options ) throws XmlException {
          return XmlBeans.getContextTypeLoader().parse( node, null, options ); }
        
        /**
         * Loads the given {@link XMLInputStream} into an XmlObject.
         * @deprecated Superceded by JSR 173
         */ 
        public static XmlObject parse ( XMLInputStream xis ) throws XmlException, XMLStreamException {
          return XmlBeans.getContextTypeLoader().parse( xis, null, null ); }
        
        /**
         * Loads the given {@link XMLInputStream} into an XmlObject.
         * @deprecated Superceded by JSR 173
         */ 
        public static XmlObject parse ( XMLInputStream xis, XmlOptions options ) throws XmlException, XMLStreamException {
          return XmlBeans.getContextTypeLoader().parse( xis, null, options ); }

        /**
         * Returns an {@link XmlSaxHandler} that can load an XmlObject from SAX events.
         */ 
        public static XmlSaxHandler newXmlSaxHandler ( ) {
          return XmlBeans.getContextTypeLoader().newXmlSaxHandler( null, null ); }
            
        /**
         * Returns an {@link XmlSaxHandler} that can load an XmlObject from SAX events.
         */ 
        public static XmlSaxHandler newXmlSaxHandler ( XmlOptions options ) {
          return XmlBeans.getContextTypeLoader().newXmlSaxHandler( null, options ); }
            
        /**
         * Returns a new validating {@link XMLInputStream} that throws exceptions when the input is not valid.
         * @deprecated Superceded by JSR 173
         */ 
        public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis ) throws XmlException, XMLStreamException {
          return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, null, null ); }
        
        /**
         * Returns a new validating {@link XMLInputStream} that throws exceptions 
         * when the input is not valid, specifying options
         * for the root element's document type and/or the collection object to use
         * as an error listener while validating.</p>
         * 
         * <p>Use the <em>options</em> parameter to specify the following:</p>
         * 
         * <ul>
         * <li>A collection instance that should be used as an error listener during
         * compilation, as described in {@link XmlOptions#setErrorListener}.</li>
         * <li>The document type for the root element, as described in 
         * {@link XmlOptions#setDocumentType(SchemaType)}.</li>
         * </ul>
         * 
         * @param xis The basis for the new XMLInputStream.
         * @param options Options specifying root document type and/or an error listener.
         * @return A new validating XMLInputStream.
         * @deprecated Superceded by JSR 173
         */ 
        public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, XmlOptions options ) throws XmlException, XMLStreamException {
          return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, null, options ); }
        
        /**
         * Instances cannot be created.
         */ 
        private Factory() { }
    }
}
