/*
 * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed 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.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.sql;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

import javax.xml.transform.Result;
import javax.xml.transform.Source;

// Android-changed: Removed @see tag (target does not exist on Android):
// @see javax.xml.stream
/**
 * The mapping in the JavaTM programming language for the SQL XML type.
 * XML is a built-in type that stores an XML value
 * as a column value in a row of a database table.
 * By default drivers implement an SQLXML object as
 * a logical pointer to the XML data
 * rather than the data itself.
 * An SQLXML object is valid for the duration of the transaction in which it was created.
 * <p>
 * The SQLXML interface provides methods for accessing the XML value
 * as a String, a Reader or Writer, or as a Stream.  The XML value
 * may also be accessed through a Source or set as a Result, which
 * are used with XML Parser APIs such as DOM, SAX, and StAX, as
 * well as with XSLT transforms and XPath evaluations.
 * <p>
 * Methods in the interfaces ResultSet, CallableStatement, and PreparedStatement,
 * such as getSQLXML allow a programmer to access an XML value.
 * In addition, this interface has methods for updating an XML value.
 * <p>
 * The XML value of the SQLXML instance may be obtained as a BinaryStream using
 * <pre>
 *   SQLXML sqlxml = resultSet.getSQLXML(column);
 *   InputStream binaryStream = sqlxml.getBinaryStream();
 * </pre>
 * For example, to parse an XML value with a DOM parser:
 * <pre>
 *   DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 *   Document result = parser.parse(binaryStream);
 * </pre>
 * or to parse an XML value with a SAX parser to your handler:
 * <pre>
 *   SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
 *   parser.parse(binaryStream, myHandler);
 * </pre>
 * or to parse an XML value with a StAX parser:
 * <pre>
 *   XMLInputFactory factory = XMLInputFactory.newInstance();
 *   XMLStreamReader streamReader = factory.createXMLStreamReader(binaryStream);
 * </pre>
 * <p>
 * Because databases may use an optimized representation for the XML,
 * accessing the value through getSource() and
 * setResult() can lead to improved processing performance
 * without serializing to a stream representation and parsing the XML.
 * <p>
 * For example, to obtain a DOM Document Node:
 * <pre>
 *   DOMSource domSource = sqlxml.getSource(DOMSource.class);
 *   Document document = (Document) domSource.getNode();
 * </pre>
 * or to set the value to a DOM Document Node to myNode:
 * <pre>
 *   DOMResult domResult = sqlxml.setResult(DOMResult.class);
 *   domResult.setNode(myNode);
 * </pre>
 * or, to send SAX events to your handler:
 * <pre>
 *   SAXSource saxSource = sqlxml.getSource(SAXSource.class);
 *   XMLReader xmlReader = saxSource.getXMLReader();
 *   xmlReader.setContentHandler(myHandler);
 *   xmlReader.parse(saxSource.getInputSource());
 * </pre>
 * or, to set the result value from SAX events:
 * <pre>
 *   SAXResult saxResult = sqlxml.setResult(SAXResult.class);
 *   ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
 *   contentHandler.startDocument();
 *   // set the XML elements and attributes into the result
 *   contentHandler.endDocument();
 * </pre>
 * or, to obtain StAX events:
 * <pre>
 *   StAXSource staxSource = sqlxml.getSource(StAXSource.class);
 *   XMLStreamReader streamReader = staxSource.getXMLStreamReader();
 * </pre>
 * or, to set the result value from StAX events:
 * <pre>
 *   StAXResult staxResult = sqlxml.setResult(StAXResult.class);
 *   XMLStreamWriter streamWriter = staxResult.getXMLStreamWriter();
 * </pre>
 * or, to perform XSLT transformations on the XML value using the XSLT in xsltFile
 * output to file resultFile:
 * <pre>
 *   File xsltFile = new File("a.xslt");
 *   File myFile = new File("result.xml");
 *   Transformer xslt = TransformerFactory.newInstance().newTransformer(new StreamSource(xsltFile));
 *   Source source = sqlxml.getSource(null);
 *   Result result = new StreamResult(myFile);
 *   xslt.transform(source, result);
 * </pre>
 * or, to evaluate an XPath expression on the XML value:
 * <pre>
 *   XPath xpath = XPathFactory.newInstance().newXPath();
 *   DOMSource domSource = sqlxml.getSource(DOMSource.class);
 *   Document document = (Document) domSource.getNode();
 *   String expression = "/foo/@bar";
 *   String barValue = xpath.evaluate(expression, document);
 * </pre>
 * To set the XML value to be the result of an XSLT transform:
 * <pre>
 *   File sourceFile = new File("source.xml");
 *   Transformer xslt = TransformerFactory.newInstance().newTransformer(new StreamSource(xsltFile));
 *   Source streamSource = new StreamSource(sourceFile);
 *   Result result = sqlxml.setResult(null);
 *   xslt.transform(streamSource, result);
 * </pre>
 * Any Source can be transformed to a Result using the identity transform
 * specified by calling newTransformer():
 * <pre>
 *   Transformer identity = TransformerFactory.newInstance().newTransformer();
 *   Source source = sqlxml.getSource(null);
 *   File myFile = new File("result.xml");
 *   Result result = new StreamResult(myFile);
 *   identity.transform(source, result);
 * </pre>
 * To write the contents of a Source to standard output:
 * <pre>
 *   Transformer identity = TransformerFactory.newInstance().newTransformer();
 *   Source source = sqlxml.getSource(null);
 *   Result result = new StreamResult(System.out);
 *   identity.transform(source, result);
 * </pre>
 * To create a DOMSource from a DOMResult:
 * <pre>
 *    DOMSource domSource = new DOMSource(domResult.getNode());
 * </pre>
 * <p>
 * Incomplete or invalid XML values may cause an SQLException when
 * set or the exception may occur when execute() occurs.  All streams
 * must be closed before execute() occurs or an SQLException will be thrown.
 * <p>
 * Reading and writing XML values to or from an SQLXML object can happen at most once.
 * The conceptual states of readable and not readable determine if one
 * of the reading APIs will return a value or throw an exception.
 * The conceptual states of writable and not writable determine if one
 * of the writing APIs will set a value or throw an exception.
 * <p>
 * The state moves from readable to not readable once free() or any of the
 * reading APIs are called: getBinaryStream(), getCharacterStream(), getSource(), and getString().
 * Implementations may also change the state to not writable when this occurs.
 * <p>
 * The state moves from writable to not writeable once free() or any of the
 * writing APIs are called: setBinaryStream(), setCharacterStream(), setResult(), and setString().
 * Implementations may also change the state to not readable when this occurs.
 * <p>
  * <p>
 * All methods on the <code>SQLXML</code> interface must be fully implemented if the
 * JDBC driver supports the data type.
 *
 * @see javax.xml.parsers
 * @see javax.xml.transform
 * @see javax.xml.xpath
 * @since 1.6
 */
public interface SQLXML
{
  /**
   * This method closes this object and releases the resources that it held.
   * The SQL XML object becomes invalid and neither readable or writeable
   * when this method is called.
   *
   * After <code>free</code> has been called, any attempt to invoke a
   * method other than <code>free</code> will result in a <code>SQLException</code>
   * being thrown.  If <code>free</code> is called multiple times, the subsequent
   * calls to <code>free</code> are treated as a no-op.
   * @throws SQLException if there is an error freeing the XML value.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  void free() throws SQLException;

  /**
   * Retrieves the XML value designated by this SQLXML instance as a stream.
   * The bytes of the input stream are interpreted according to appendix F of the XML 1.0 specification.
   * The behavior of this method is the same as ResultSet.getBinaryStream()
   * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
   * <p>
   * The SQL XML object becomes not readable when this method is called and
   * may also become not writable depending on implementation.
   *
   * @return a stream containing the XML data.
   * @throws SQLException if there is an error processing the XML value.
   *   An exception is thrown if the state is not readable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  InputStream getBinaryStream() throws SQLException;

  /**
   * Retrieves a stream that can be used to write the XML value that this SQLXML instance represents.
   * The stream begins at position 0.
   * The bytes of the stream are interpreted according to appendix F of the XML 1.0 specification
   * The behavior of this method is the same as ResultSet.updateBinaryStream()
   * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
   * <p>
   * The SQL XML object becomes not writeable when this method is called and
   * may also become not readable depending on implementation.
   *
   * @return a stream to which data can be written.
   * @throws SQLException if there is an error processing the XML value.
   *   An exception is thrown if the state is not writable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  OutputStream setBinaryStream() throws SQLException;

  /**
   * Retrieves the XML value designated by this SQLXML instance as a java.io.Reader object.
   * The format of this stream is defined by org.xml.sax.InputSource,
   * where the characters in the stream represent the unicode code points for
   * XML according to section 2 and appendix B of the XML 1.0 specification.
   * Although an encoding declaration other than unicode may be present,
   * the encoding of the stream is unicode.
   * The behavior of this method is the same as ResultSet.getCharacterStream()
   * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
   * <p>
   * The SQL XML object becomes not readable when this method is called and
   * may also become not writable depending on implementation.
   *
   * @return a stream containing the XML data.
   * @throws SQLException if there is an error processing the XML value.
   *   The getCause() method of the exception may provide a more detailed exception, for example,
   *   if the stream does not contain valid characters.
   *   An exception is thrown if the state is not readable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  Reader getCharacterStream() throws SQLException;

  /**
   * Retrieves a stream to be used to write the XML value that this SQLXML instance represents.
   * The format of this stream is defined by org.xml.sax.InputSource,
   * where the characters in the stream represent the unicode code points for
   * XML according to section 2 and appendix B of the XML 1.0 specification.
   * Although an encoding declaration other than unicode may be present,
   * the encoding of the stream is unicode.
   * The behavior of this method is the same as ResultSet.updateCharacterStream()
   * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
   * <p>
   * The SQL XML object becomes not writeable when this method is called and
   * may also become not readable depending on implementation.
   *
   * @return a stream to which data can be written.
   * @throws SQLException if there is an error processing the XML value.
   *   The getCause() method of the exception may provide a more detailed exception, for example,
   *   if the stream does not contain valid characters.
   *   An exception is thrown if the state is not writable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  Writer setCharacterStream() throws SQLException;

  /**
   * Returns a string representation of the XML value designated by this SQLXML instance.
   * The format of this String is defined by org.xml.sax.InputSource,
   * where the characters in the stream represent the unicode code points for
   * XML according to section 2 and appendix B of the XML 1.0 specification.
   * Although an encoding declaration other than unicode may be present,
   * the encoding of the String is unicode.
   * The behavior of this method is the same as ResultSet.getString()
   * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
   * <p>
   * The SQL XML object becomes not readable when this method is called and
   * may also become not writable depending on implementation.
   *
   * @return a string representation of the XML value designated by this SQLXML instance.
   * @throws SQLException if there is an error processing the XML value.
   *   The getCause() method of the exception may provide a more detailed exception, for example,
   *   if the stream does not contain valid characters.
   *   An exception is thrown if the state is not readable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  String getString() throws SQLException;

  /**
   * Sets the XML value designated by this SQLXML instance to the given String representation.
   * The format of this String is defined by org.xml.sax.InputSource,
   * where the characters in the stream represent the unicode code points for
   * XML according to section 2 and appendix B of the XML 1.0 specification.
   * Although an encoding declaration other than unicode may be present,
   * the encoding of the String is unicode.
   * The behavior of this method is the same as ResultSet.updateString()
   * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
   * <p>
   * The SQL XML object becomes not writeable when this method is called and
   * may also become not readable depending on implementation.
   *
   * @param value the XML value
   * @throws SQLException if there is an error processing the XML value.
   *   The getCause() method of the exception may provide a more detailed exception, for example,
   *   if the stream does not contain valid characters.
   *   An exception is thrown if the state is not writable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  void setString(String value) throws SQLException;

  /**
   * Returns a Source for reading the XML value designated by this SQLXML instance.
   * Sources are used as inputs to XML parsers and XSLT transformers.
   * <p>
   * Sources for XML parsers will have namespace processing on by default.
   * The systemID of the Source is implementation dependent.
   * <p>
   * The SQL XML object becomes not readable when this method is called and
   * may also become not writable depending on implementation.
   * <p>
   * Note that SAX is a callback architecture, so a returned
   * SAXSource should then be set with a content handler that will
   * receive the SAX events from parsing.  The content handler
   * will receive callbacks based on the contents of the XML.
   * <pre>
   *   SAXSource saxSource = sqlxml.getSource(SAXSource.class);
   *   XMLReader xmlReader = saxSource.getXMLReader();
   *   xmlReader.setContentHandler(myHandler);
   *   xmlReader.parse(saxSource.getInputSource());
   * </pre>
   *
   * @param sourceClass The class of the source, or null.
   * If the class is null, a vendor specifc Source implementation will be returned.
   * The following classes are supported at a minimum:
   * <pre>
   *   javax.xml.transform.dom.DOMSource - returns a DOMSource
   *   javax.xml.transform.sax.SAXSource - returns a SAXSource
   *   javax.xml.transform.stax.StAXSource - returns a StAXSource
   *   javax.xml.transform.stream.StreamSource - returns a StreamSource
   * </pre>
   * @return a Source for reading the XML value.
   * @throws SQLException if there is an error processing the XML value
   *   or if this feature is not supported.
   *   The getCause() method of the exception may provide a more detailed exception, for example,
   *   if an XML parser exception occurs.
   *   An exception is thrown if the state is not readable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  <T extends Source> T getSource(Class<T> sourceClass) throws SQLException;

  /**
   * Returns a Result for setting the XML value designated by this SQLXML instance.
   * <p>
   * The systemID of the Result is implementation dependent.
   * <p>
   * The SQL XML object becomes not writeable when this method is called and
   * may also become not readable depending on implementation.
   * <p>
   * Note that SAX is a callback architecture and the returned
   * SAXResult has a content handler assigned that will receive the
   * SAX events based on the contents of the XML.  Call the content
   * handler with the contents of the XML document to assign the values.
   * <pre>
   *   SAXResult saxResult = sqlxml.setResult(SAXResult.class);
   *   ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
   *   contentHandler.startDocument();
   *   // set the XML elements and attributes into the result
   *   contentHandler.endDocument();
   * </pre>
   *
   * @param resultClass The class of the result, or null.
   * If resultClass is null, a vendor specific Result implementation will be returned.
   * The following classes are supported at a minimum:
   * <pre>
   *   javax.xml.transform.dom.DOMResult - returns a DOMResult
   *   javax.xml.transform.sax.SAXResult - returns a SAXResult
   *   javax.xml.transform.stax.StAXResult - returns a StAXResult
   *   javax.xml.transform.stream.StreamResult - returns a StreamResult
   * </pre>
   * @return Returns a Result for setting the XML value.
   * @throws SQLException if there is an error processing the XML value
   *   or if this feature is not supported.
   *   The getCause() method of the exception may provide a more detailed exception, for example,
   *   if an XML parser exception occurs.
   *   An exception is thrown if the state is not writable.
   * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
   * this method
   * @since 1.6
   */
  <T extends Result> T setResult(Class<T> resultClass) throws SQLException;

}
