org.postgresql.jdbc.PgSQLXML Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of postgresql Show documentation
Show all versions of postgresql Show documentation
PostgreSQL JDBC Driver JDBC4
/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
package org.postgresql.jdbc;
import org.postgresql.core.BaseConnection;
import org.postgresql.util.GT;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.sql.SQLException;
import java.sql.SQLXML;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
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.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class PgSQLXML implements SQLXML {
private final BaseConnection _conn;
private String _data; // The actual data contained.
private boolean _initialized; // Has someone assigned the data for this object?
private boolean _active; // Is anyone in the process of loading data into us?
private boolean _freed;
private ByteArrayOutputStream _byteArrayOutputStream;
private StringWriter _stringWriter;
private DOMResult _domResult;
public PgSQLXML(BaseConnection conn) {
this(conn, null, false);
}
public PgSQLXML(BaseConnection conn, String data) {
this(conn, data, true);
}
private PgSQLXML(BaseConnection conn, String data, boolean initialized) {
_conn = conn;
_data = data;
_initialized = initialized;
_active = false;
_freed = false;
}
public synchronized void free() {
_freed = true;
_data = null;
}
public synchronized InputStream getBinaryStream() throws SQLException {
checkFreed();
ensureInitialized();
if (_data == null) {
return null;
}
try {
return new ByteArrayInputStream(_conn.getEncoding().encode(_data));
} catch (IOException ioe) {
// This should be a can't happen exception. We just
// decoded this data, so it would be surprising that
// we couldn't encode it.
// For this reason don't make it translatable.
throw new PSQLException("Failed to re-encode xml data.", PSQLState.DATA_ERROR, ioe);
}
}
public synchronized Reader getCharacterStream() throws SQLException {
checkFreed();
ensureInitialized();
if (_data == null) {
return null;
}
return new StringReader(_data);
}
// We must implement this unsafely because that's what the
// interface requires. Because it says we're returning T
// which is unknown, none of the return values can satisfy it
// as Java isn't going to understand the if statements that
// ensure they are the same.
//
public synchronized T getSource(Class sourceClass) throws SQLException {
checkFreed();
ensureInitialized();
if (_data == null) {
return null;
}
try {
if (sourceClass == null || DOMSource.class.equals(sourceClass)) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new NonPrintingErrorHandler());
InputSource input = new InputSource(new StringReader(_data));
return (T) new DOMSource(builder.parse(input));
} else if (SAXSource.class.equals(sourceClass)) {
InputSource is = new InputSource(new StringReader(_data));
return (T) new SAXSource(is);
} else if (StreamSource.class.equals(sourceClass)) {
return (T) new StreamSource(new StringReader(_data));
} else if (StAXSource.class.equals(sourceClass)) {
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(_data));
return (T) new StAXSource(xsr);
}
} catch (Exception e) {
throw new PSQLException(GT.tr("Unable to decode xml data."), PSQLState.DATA_ERROR, e);
}
throw new PSQLException(GT.tr("Unknown XML Source class: {0}", sourceClass),
PSQLState.INVALID_PARAMETER_TYPE);
}
public synchronized String getString() throws SQLException {
checkFreed();
ensureInitialized();
return _data;
}
public synchronized OutputStream setBinaryStream() throws SQLException {
checkFreed();
initialize();
_active = true;
_byteArrayOutputStream = new ByteArrayOutputStream();
return _byteArrayOutputStream;
}
public synchronized Writer setCharacterStream() throws SQLException {
checkFreed();
initialize();
_stringWriter = new StringWriter();
return _stringWriter;
}
public synchronized T setResult(Class resultClass) throws SQLException {
checkFreed();
initialize();
if (resultClass == null || DOMResult.class.equals(resultClass)) {
_domResult = new DOMResult();
_active = true;
return (T) _domResult;
} else if (SAXResult.class.equals(resultClass)) {
try {
SAXTransformerFactory transformerFactory =
(SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler transformerHandler = transformerFactory.newTransformerHandler();
_stringWriter = new StringWriter();
transformerHandler.setResult(new StreamResult(_stringWriter));
_active = true;
return (T) new SAXResult(transformerHandler);
} catch (TransformerException te) {
throw new PSQLException(GT.tr("Unable to create SAXResult for SQLXML."),
PSQLState.UNEXPECTED_ERROR, te);
}
} else if (StreamResult.class.equals(resultClass)) {
_stringWriter = new StringWriter();
_active = true;
return (T) new StreamResult(_stringWriter);
} else if (StAXResult.class.equals(resultClass)) {
_stringWriter = new StringWriter();
try {
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter xsw = xof.createXMLStreamWriter(_stringWriter);
_active = true;
return (T) new StAXResult(xsw);
} catch (XMLStreamException xse) {
throw new PSQLException(GT.tr("Unable to create StAXResult for SQLXML"),
PSQLState.UNEXPECTED_ERROR, xse);
}
}
throw new PSQLException(GT.tr("Unknown XML Result class: {0}", resultClass),
PSQLState.INVALID_PARAMETER_TYPE);
}
public synchronized void setString(String value) throws SQLException {
checkFreed();
initialize();
_data = value;
}
private void checkFreed() throws SQLException {
if (_freed) {
throw new PSQLException(GT.tr("This SQLXML object has already been freed."),
PSQLState.OBJECT_NOT_IN_STATE);
}
}
private void ensureInitialized() throws SQLException {
if (!_initialized) {
throw new PSQLException(
GT.tr(
"This SQLXML object has not been initialized, so you cannot retrieve data from it."),
PSQLState.OBJECT_NOT_IN_STATE);
}
// Is anyone loading data into us at the moment?
if (!_active) {
return;
}
if (_byteArrayOutputStream != null) {
try {
_data = _conn.getEncoding().decode(_byteArrayOutputStream.toByteArray());
} catch (IOException ioe) {
throw new PSQLException(GT.tr("Failed to convert binary xml data to encoding: {0}.",
_conn.getEncoding().name()), PSQLState.DATA_ERROR, ioe);
} finally {
_byteArrayOutputStream = null;
_active = false;
}
} else if (_stringWriter != null) {
// This is also handling the work for Stream, SAX, and StAX Results
// as they will use the same underlying stringwriter variable.
//
_data = _stringWriter.toString();
_stringWriter = null;
_active = false;
} else if (_domResult != null) {
// Copy the content from the result to a source
// and use the identify transform to get it into a
// friendlier result format.
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource domSource = new DOMSource(_domResult.getNode());
StringWriter stringWriter = new StringWriter();
StreamResult streamResult = new StreamResult(stringWriter);
transformer.transform(domSource, streamResult);
_data = stringWriter.toString();
} catch (TransformerException te) {
throw new PSQLException(GT.tr("Unable to convert DOMResult SQLXML data to a string."),
PSQLState.DATA_ERROR, te);
} finally {
_domResult = null;
_active = false;
}
}
}
private void initialize() throws SQLException {
if (_initialized) {
throw new PSQLException(
GT.tr(
"This SQLXML object has already been initialized, so you cannot manipulate it further."),
PSQLState.OBJECT_NOT_IN_STATE);
}
_initialized = true;
}
// Don't clutter System.err with errors the user can't silence.
// If something bad really happens an exception will be thrown.
static class NonPrintingErrorHandler implements ErrorHandler {
public void error(SAXParseException e) {
}
public void fatalError(SAXParseException e) {
}
public void warning(SAXParseException e) {
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy