com.foundationdb.sql.jdbc.jdbc4.Jdbc4SQLXML Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fdb-sql-layer-jdbc Show documentation
Show all versions of fdb-sql-layer-jdbc Show documentation
The FoundationDB SQL Layer Driver for JDBC4
package com.foundationdb.sql.jdbc.jdbc4;
import java.io.*;
import java.sql.SQLXML;
import java.sql.SQLException;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.dom.DOMResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXResult;
import org.xml.sax.InputSource;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
import com.foundationdb.sql.jdbc.core.BaseConnection;
import com.foundationdb.sql.jdbc.util.GT;
import com.foundationdb.sql.jdbc.util.PSQLException;
import com.foundationdb.sql.jdbc.util.PSQLState;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stax.StAXResult;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.XMLStreamException;
public class Jdbc4SQLXML 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 Jdbc4SQLXML(BaseConnection conn)
{
this(conn, null, false);
}
public Jdbc4SQLXML(BaseConnection conn, String data)
{
this(conn, data, true);
}
private Jdbc4SQLXML(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 Source 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 new DOMSource(builder.parse(input));
}
else if (SAXSource.class.equals(sourceClass))
{
InputSource is = new InputSource(new StringReader(_data));
return new SAXSource(is);
}
else if (StreamSource.class.equals(sourceClass))
{
return new StreamSource(new StringReader(_data));
}
else if (StAXSource.class.equals(sourceClass))
{
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(_data));
return 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 Result setResult(Class resultClass) throws SQLException
{
checkFreed();
initialize();
if (resultClass == null || DOMResult.class.equals(resultClass)) {
_domResult = new DOMResult();
_active = true;
return _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 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 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 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 - 2024 Weber Informatics LLC | Privacy Policy