/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/OracleRDBMSAdapter.java,v 1.9.2.3 2004/11/13 14:42:00 dsavazzi Exp $
* $Revision: 1.9.2.3 $
* $Date: 2004/11/13 14:42:00 $
*
* ====================================================================
*
* Copyright 1999-2003 The Apache Software Foundation
*
* 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.apache.slide.store.impl.rdbms;
import java.io.*;
import java.lang.reflect.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.slide.common.Uri;
import org.apache.slide.common.Service;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.util.logger.Logger;
/**
* Adapter for Oracle 9 and 10.
*
* @version $Revision: 1.9.2.3 $
*/
public class OracleRDBMSAdapter extends CommonRDBMSAdapter implements SequenceAdapter {
// Constructor
public OracleRDBMSAdapter(Service service, Logger logger)
throws ClassNotFoundException, NoSuchMethodException
{
super(service, logger);
Class bCls = Class.forName("oracle.sql.BLOB");
blobGetOutStreamMethod = bCls.getMethod("getBinaryOutputStream", new Class[] {});
}
// Public Methods
protected void storeContent(
Connection connection, Uri uri,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent) throws IOException, SQLException
{
assureVersionInfo(connection, uri, revisionDescriptor);
InputStream is = revisionContent.streamContent();
if (is != null) {
long blobLength = 0;
File tempFile = null;
if (bcompress) {
getLogger().log("Compressing the data", LOG_CHANNEL,
Logger.DEBUG);
StoreContentZip ziputil = new StoreContentZip();
ziputil.Zip(is);
is = ziputil.getInputStream();
// fix RevisionDescriptor Content Length
if (revisionDescriptor.getContentLength() == -1) {
revisionDescriptor.setContentLength(ziputil.getInitialContentLength());
}
blobLength = ziputil.getContentLength();
} else {
// fix RevisionDescriptor Content Length
if (revisionDescriptor.getContentLength() == -1) {
try {
tempFile = File.createTempFile("content", null);
FileOutputStream fos = new FileOutputStream(tempFile);
try {
byte buffer[] = new byte[4096];
do {
int nChar = is.read(buffer);
if (nChar == -1) {
break;
}
fos.write(buffer, 0, nChar);
} while (true);
} finally {
fos.close();
}
is.close();
is = new FileInputStream(tempFile);
revisionDescriptor.setContentLength(tempFile.length());
} catch (IOException ex) {
getLogger().log(ex.toString() + " during the calculation of the content length.",
LOG_CHANNEL, Logger.ERROR);
throw ex;
}
}
blobLength = revisionDescriptor.getContentLength();
}
CallableStatement statement = null;
try {
long versionID = getVersionID(connection, uri.toString(), revisionDescriptor);
statement = connection.prepareCall(
"BEGIN "
+ "insert into VERSION_CONTENT (VERSION_ID, CONTENT) "
+ "values (?, empty_blob()) RETURN CONTENT into ?;"
+ "END; "
);
statement.setLong(1, versionID);
statement.registerOutParameter(2, java.sql.Types.BLOB);
statement.executeUpdate();
// do these two lines using reflection
// BLOB blob = (BLOB) statement.getBlob(2);
// OutputStream os = blob.getBinaryOutputStream();
Object bObj = statement.getBlob(2);
OutputStream os = null;
try {
os = (OutputStream) blobGetOutStreamMethod.invoke(bObj, new Object[] {});
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException("Reflection error");
}
try {
byte buffer[] = new byte[4096];
do {
int nChar = is.read(buffer);
if (nChar == -1) {
break;
}
os.write(buffer, 0, nChar);
} while (true);
} finally {
os.flush();
os.close();
}
} finally {
if (tempFile != null) {
try {
is.close();
} catch (Exception ex) {
// ignore
}
is = null;
if (!tempFile.delete()) {
logger.log("Could not delete file \"" + tempFile.getAbsolutePath() +
"\"");
}
}
try {
close(statement);
} finally {
if (is != null) {
// XXX some JDBC drivers seem to close the stream upon
// closing of
// the statement; if so this will raise an IOException
// silently ignore it...
try {
is.close();
} catch (IOException ioe) {
logger.log("Could not close stream", ioe, LOG_CHANNEL, Logger.DEBUG);
}
}
}
}
}
}
protected static String normalizeSequenceName(String sequenceName) {
return sequenceName.replace('-', '_').toUpperCase() + "_SEQ";
}
public boolean isSequenceSupported(Connection conn) {
return true;
}
public boolean createSequence(Connection conn, String sequenceName) throws ServiceAccessException {
String query = "CREATE SEQUENCE \"" + normalizeSequenceName(sequenceName) + "\"";
PreparedStatement statement = null;
try {
statement = conn.prepareStatement(query);
statement.executeUpdate();
return true;
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
close(statement);
}
}
public long nextSequenceValue(Connection conn, String sequenceName) throws ServiceAccessException {
String selectQuery = "SELECT \"" + normalizeSequenceName(sequenceName)+"\".nextval FROM DUAL";
PreparedStatement selectStatement = null;
ResultSet res = null;
try {
selectStatement = conn.prepareStatement(selectQuery);
res = selectStatement.executeQuery();
if (!res.next()) {
throw new ServiceAccessException(service, "Could not increment sequence " + sequenceName);
}
long value = res.getLong(1);
return value;
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
close(selectStatement, res);
}
}
public boolean sequenceExists(Connection conn, String sequenceName) throws ServiceAccessException {
PreparedStatement selectStatement = null;
ResultSet res = null;
try {
selectStatement =
conn.prepareStatement("ALTER SEQUENCE \"" + normalizeSequenceName(sequenceName) + "\" INCREMENT BY 1");
res = selectStatement.executeQuery();
return true;
} catch (SQLException e) {
return false;
} finally {
close(selectStatement, res);
}
}
// Attributes
protected Method blobGetOutStreamMethod;
}