📄 jdbc4mysqlsqlxml.java
字号:
/*
Copyright 2002-2007 MySQL AB, 2008 Sun Microsystems
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
There are special exceptions to the terms and conditions of the GPL
as it is applied to this software. View the full text of the
exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
software distribution.
This program 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 for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.mysql.jdbc;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.SAXException;
public class JDBC4MysqlSQLXML implements SQLXML {
private XMLInputFactory inputFactory;
private XMLOutputFactory outputFactory;
private String stringRep;
private ResultSetInternalMethods owningResultSet;
private int columnIndexOfXml;
private boolean fromResultSet;
private boolean isClosed = false;
private boolean workingWithResult;
private DOMResult asDOMResult;
private SAXResult asSAXResult;
private SimpleSaxToReader saxToReaderConverter;
private StringWriter asStringWriter;
private ByteArrayOutputStream asByteArrayOutputStream;
protected JDBC4MysqlSQLXML(ResultSetInternalMethods owner, int index) {
this.owningResultSet = owner;
this.columnIndexOfXml = index;
this.fromResultSet = true;
}
protected JDBC4MysqlSQLXML() {
this.fromResultSet = false;
}
public synchronized void free() throws SQLException {
this.stringRep = null;
this.asDOMResult = null;
this.asSAXResult = null;
this.inputFactory = null;
this.outputFactory = null;
this.owningResultSet = null;
this.workingWithResult = false;
this.isClosed = true;
}
public synchronized String getString() throws SQLException {
checkClosed();
checkWorkingWithResult();
if (this.fromResultSet) {
return this.owningResultSet.getString(this.columnIndexOfXml);
}
return this.stringRep;
}
private synchronized void checkClosed() throws SQLException {
if (this.isClosed) {
throw SQLError
.createSQLException("SQLXMLInstance has been free()d");
}
}
private synchronized void checkWorkingWithResult() throws SQLException {
if (this.workingWithResult) {
throw SQLError
.createSQLException(
"Can't perform requested operation after getResult() has been called to write XML data",
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
}
}
/**
* 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
*/
public synchronized void setString(String str) throws SQLException {
checkClosed();
checkWorkingWithResult();
this.stringRep = str;
this.fromResultSet = false;
}
public synchronized boolean isEmpty() throws SQLException {
checkClosed();
checkWorkingWithResult();
if (!this.fromResultSet) {
return this.stringRep == null || this.stringRep.length() == 0;
}
return false;
}
public synchronized InputStream getBinaryStream() throws SQLException {
checkClosed();
checkWorkingWithResult();
return this.owningResultSet.getBinaryStream(this.columnIndexOfXml);
}
/**
* 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
*/
public synchronized Reader getCharacterStream() throws SQLException {
checkClosed();
checkWorkingWithResult();
return this.owningResultSet.getCharacterStream(this.columnIndexOfXml);
}
/**
* 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:
*
* (MySQL returns a SAXSource if sourceClass == null)
*
* <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
*/
public synchronized Source getSource(Class clazz) throws SQLException {
checkClosed();
checkWorkingWithResult();
// Note that we try and use streams here wherever possible
// for the day that the server actually supports streaming
// from server -> client (futureproofing)
if (clazz == null || clazz.equals(SAXSource.class)) {
InputSource inputSource = null;
if (this.fromResultSet) {
inputSource = new InputSource(this.owningResultSet
.getCharacterStream(this.columnIndexOfXml));
} else {
inputSource = new InputSource(new StringReader(this.stringRep));
}
return new SAXSource(inputSource);
} else if (clazz.equals(DOMSource.class)) {
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory
.newInstance();
builderFactory.setNamespaceAware(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
InputSource inputSource = null;
if (this.fromResultSet) {
inputSource = new InputSource(this.owningResultSet
.getCharacterStream(this.columnIndexOfXml));
} else {
inputSource = new InputSource(new StringReader(
this.stringRep));
}
return new DOMSource(builder.parse(inputSource));
} catch (Throwable t) {
SQLException sqlEx = SQLError.createSQLException(t
.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
sqlEx.initCause(t);
throw sqlEx;
}
} else if (clazz.equals(StreamSource.class)) {
Reader reader = null;
if (this.fromResultSet) {
reader = this.owningResultSet
.getCharacterStream(this.columnIndexOfXml);
} else {
reader = new StringReader(this.stringRep);
}
return new StreamSource(reader);
} else if (clazz.equals(StAXSource.class)) {
try {
Reader reader = null;
if (this.fromResultSet) {
reader = this.owningResultSet
.getCharacterStream(this.columnIndexOfXml);
} else {
reader = new StringReader(this.stringRep);
}
return new StAXSource(this.inputFactory
.createXMLStreamReader(reader));
} catch (XMLStreamException ex) {
SQLException sqlEx = SQLError.createSQLException(ex
.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
sqlEx.initCause(ex);
throw sqlEx;
}
} else {
throw SQLError.createSQLException("XML Source of type \""
+ clazz.toString() + "\" Not supported.",
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
}
}
/**
* 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
*/
public synchronized OutputStream setBinaryStream() throws SQLException {
checkClosed();
checkWorkingWithResult();
this.workingWithResult = true;
return setBinaryStreamInternal();
}
private synchronized OutputStream setBinaryStreamInternal()
throws SQLException {
this.asByteArrayOutputStream = new ByteArrayOutputStream();
return this.asByteArrayOutputStream;
}
/**
* 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -