/*
* Copyright 2008-2010 the original author or authors.
*
* Licensed 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.
*/
package org.springframework.data.jdbc.support.oracle;
import oracle.jdbc.OracleTypes;
import oracle.xdb.XMLType;
import org.springframework.jdbc.support.xml.SqlXmlValue;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.MarshallingFailureException;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* Implementation of the SqlXmlValue interface, for convenient
* creation of type values that are provided As an XML Document.
*
* <p>A usage example from a StoredProcedure:
*
* <pre class="code">proc.declareParameter(new SqlParameter("myXml", OracleTypes.OPAQUE, "SYS.XMLTYPE"));
* ...
*
* Map in = new HashMap();
* in.put("myXml", new OracleXmlTypeMarshallingValue(object, marshaller);
* Map out = proc.execute(in);
* </pre>
*
* @author Thomas Risberg
* @since 1.0
* @see org.springframework.jdbc.support.xml.SqlXmlValue
* @see org.springframework.jdbc.support.SqlValue
*/
public class OracleXmlTypeMarshallingValue implements SqlXmlValue {
private Object value;
private Marshaller marshaller;
private XMLType xmlValue;
/**
* Constructor that takes a parameter with the Object value and another with
* the <code>Marshaller</code> to be used.
* @param value the <code>Object</code> containing the object to be marshalled.
*/
public OracleXmlTypeMarshallingValue(Object value, Marshaller marshaller) {
this.value = value;
this.marshaller = marshaller;
}
/**
* The implementation for this specific type. This method is called internally by the
* Spring Framework during the out parameter processing and it's not accessed by appplication
* code directly.
* @see org.springframework.jdbc.support.xml.SqlXmlValue
*/
public void setValue(PreparedStatement ps, int paramIndex) throws SQLException {
Connection conn = ps.getConnection();
StreamResult result = new StreamResult();
ByteArrayOutputStream os = new ByteArrayOutputStream();
result.setOutputStream(os);
String stringValue = null;
try {
marshaller.marshal(value, result);
stringValue = os.toString();
}
catch (IOException e) {
throw new MarshallingFailureException("Error marshalling xml data from object " + value.getClass().getName() + ": ");
}
finally {
try {
os.close();
} catch (IOException ignore) {}
}
xmlValue = new XMLType(conn, stringValue);
ps.setObject(paramIndex, xmlValue, OracleTypes.OPAQUE);
}
/**
* Close the XMLType
*/
public void cleanup() {
if (xmlValue != null) {
xmlValue.close();
}
}
}