📄 jdbc4mysqlsqlxml.java
字号:
* 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 Writer setCharacterStream() throws SQLException {
checkClosed();
checkWorkingWithResult();
this.workingWithResult = true;
return setCharacterStreamInternal();
}
private synchronized Writer setCharacterStreamInternal()
throws SQLException {
this.asStringWriter = new StringWriter();
return this.asStringWriter;
}
/**
* 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
*/
public synchronized Result setResult(Class clazz) throws SQLException {
checkClosed();
checkWorkingWithResult();
this.workingWithResult = true;
this.asDOMResult = null;
this.asSAXResult = null;
this.saxToReaderConverter = null;
this.stringRep = null;
this.asStringWriter = null;
this.asByteArrayOutputStream = null;
if (clazz == null || clazz.equals(SAXResult.class)) {
this.saxToReaderConverter = new SimpleSaxToReader();
this.asSAXResult = new SAXResult(this.saxToReaderConverter);
return this.asSAXResult;
} else if (clazz.equals(DOMResult.class)) {
this.asDOMResult = new DOMResult();
return this.asDOMResult;
} else if (clazz.equals(StreamResult.class)) {
return new StreamResult(setCharacterStreamInternal());
} else if (clazz.equals(StAXResult.class)) {
try {
if (this.outputFactory == null) {
this.outputFactory = XMLOutputFactory.newInstance();
}
return new StAXResult(this.outputFactory
.createXMLEventWriter(setCharacterStreamInternal()));
} catch (XMLStreamException ex) {
SQLException sqlEx = SQLError.createSQLException(ex
.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
sqlEx.initCause(ex);
throw sqlEx;
}
} else {
throw SQLError.createSQLException("XML Result of type \""
+ clazz.toString() + "\" Not supported.",
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
}
}
private Reader binaryInputStreamStreamToReader(ByteArrayOutputStream out) {
try {
// There's got to be an easier way to do this, but
// I don't feel like coding up Appendix F of the XML Spec
// myself, when there's a reusable way to do it, and we
// can warn folks away from BINARY xml streams that have
// to be parsed to determine the character encoding :P
String encoding = "UTF-8";
try {
ByteArrayInputStream bIn = new ByteArrayInputStream(out
.toByteArray());
XMLStreamReader reader = this.inputFactory
.createXMLStreamReader(bIn);
int eventType = 0;
while ((eventType = reader.next()) != XMLStreamReader.END_DOCUMENT) {
if (eventType == XMLStreamReader.START_DOCUMENT) {
String possibleEncoding = reader.getEncoding();
if (possibleEncoding != null) {
encoding = possibleEncoding;
}
break;
}
}
} catch (Throwable t) {
// ignore, dealt with later when the string can't be parsed
// into valid XML
}
return new StringReader(new String(out.toByteArray(), encoding));
} catch (UnsupportedEncodingException badEnc) {
throw new RuntimeException(badEnc);
}
}
protected String readerToString(Reader reader) throws SQLException {
StringBuffer buf = new StringBuffer();
int charsRead = 0;
char[] charBuf = new char[512];
try {
while ((charsRead = reader.read(charBuf)) != -1) {
buf.append(charBuf, 0, charsRead);
}
} catch (IOException ioEx) {
SQLException sqlEx = SQLError.createSQLException(ioEx
.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
sqlEx.initCause(ioEx);
throw sqlEx;
}
return buf.toString();
}
protected synchronized Reader serializeAsCharacterStream()
throws SQLException {
checkClosed();
if (this.workingWithResult) {
// figure out what kind of result
if (this.stringRep != null) {
return new StringReader(this.stringRep);
}
if (this.asDOMResult != null) {
return new StringReader(domSourceToString());
}
if (this.asStringWriter != null) { // stax result
return new StringReader(this.asStringWriter.toString());
}
if (this.asSAXResult != null) {
return this.saxToReaderConverter.toReader();
}
if (this.asByteArrayOutputStream != null) {
return binaryInputStreamStreamToReader(this.asByteArrayOutputStream);
}
}
return this.owningResultSet.getCharacterStream(this.columnIndexOfXml);
}
protected String domSourceToString() throws SQLException {
try {
DOMSource source = new DOMSource(this.asDOMResult.getNode());
Transformer identity = TransformerFactory.newInstance()
.newTransformer();
StringWriter stringOut = new StringWriter();
Result result = new StreamResult(stringOut);
identity.transform(source, result);
return stringOut.toString();
} catch (Throwable t) {
SQLException sqlEx = SQLError.createSQLException(t
.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
sqlEx.initCause(t);
throw sqlEx;
}
}
protected synchronized String serializeAsString() throws SQLException {
checkClosed();
if (this.workingWithResult) {
// figure out what kind of result
if (this.stringRep != null) {
return this.stringRep;
}
if (this.asDOMResult != null) {
return domSourceToString();
}
if (this.asStringWriter != null) { // stax result
return this.asStringWriter.toString();
}
if (this.asSAXResult != null) {
return readerToString(this.saxToReaderConverter.toReader());
}
if (this.asByteArrayOutputStream != null) {
return readerToString(
binaryInputStreamStreamToReader(this.asByteArrayOutputStream));
}
}
return this.owningResultSet.getString(this.columnIndexOfXml);
}
/*
* The SimpleSaxToReader class is an adaptation of the SAX "Writer"
* example from the Apache XercesJ-2 Project. The license for this
* code is as follows:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class SimpleSaxToReader extends DefaultHandler {
StringBuffer buf = new StringBuffer();
public void startDocument() throws SAXException {
buf.append("<?xml version='1.0' encoding='UTF-8'?>");
}
public void endDocument() throws SAXException {
// Do we need to override this?
}
public void startElement(String namespaceURI, String sName,
String qName, Attributes attrs) throws SAXException {
this.buf.append("<");
this.buf.append(qName);
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
this.buf.append(" ");
this.buf.append(attrs.getQName(i)).append("=\"");
escapeCharsForXml(attrs.getValue(i), true);
this.buf.append("\"");
}
}
this.buf.append(">");
}
public void characters(char buf[], int offset, int len)
throws SAXException {
if (!this.inCDATA) {
escapeCharsForXml(buf, offset, len, false);
} else {
this.buf.append(buf, offset, len);
}
}
public void ignorableWhitespace(char ch[], int start, int length)
throws SAXException {
characters(ch, start, length);
}
private boolean inCDATA = false;
public void startCDATA() throws SAXException {
this.buf.append("<![CDATA[");
this.inCDATA = true;
}
public void endCDATA() throws SAXException {
this.inCDATA = false;
this.buf.append("]]>");
}
public void comment(char ch[], int start, int length)
throws SAXException {
// if (!fCanonical && fElementDepth > 0) {
this.buf.append("<!--");
for (int i = 0; i < length; ++i) {
this.buf.append(ch[start + i]);
}
this.buf.append("-->");
// }
}
Reader toReader() {
return new StringReader(this.buf.toString());
}
private void escapeCharsForXml(String str, boolean isAttributeData) {
if (str == null) {
return;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
escapeCharsForXml(str.charAt(i), isAttributeData);
}
}
private void escapeCharsForXml(char[] buf, int offset, int len,
boolean isAttributeData) {
if (buf == null) {
return;
}
for (int i = 0; i < len; i++) {
escapeCharsForXml(buf[offset + i], isAttributeData);
}
}
private void escapeCharsForXml(char c, boolean isAttributeData) {
switch (c) {
case '<':
this.buf.append("<");
break;
case '>':
this.buf.append(">");
break;
case '&':
this.buf.append("&");
break;
case '"':
if (!isAttributeData) {
this.buf.append("\"");
}
else {
this.buf.append(""");
}
break;
case '\r':
this.buf.append("
");
break;
default:
if (((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A)
|| (c >= 0x7F && c <= 0x9F) || c == 0x2028)
|| isAttributeData && (c == 0x09 || c == 0x0A)) {
this.buf.append("&#x");
this.buf.append(Integer.toHexString(c).toUpperCase());
this.buf.append(";");
}
else {
this.buf.append(c);
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -