Serge,
Please find the final patch code for Oracle. You'll need to download two
vital classes from Oracle to support its JDBC driver (classes12.zip &
nls_charset12.zip for national char set support).
There are 2 classes in James which needs updating and there
JamesJDBCMailRepository and MimeMessageJDBCSource classes. Please scan for
start/end markers for oracle implemented code and note any code removal
which I've commented out, again these are held within the start/end block.
I have used Oracle's BLOB type which stores unstructured binary large
objects. BLOBs can be thought of as bitstreams with no character set
semantics. BLOBs can store up to 4 gigabytes of binary data.
So, to begin with, the code for JamesJDBCMailRepository:
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.james.mailrepository;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import javax.mail.internet.MimeMessage;
import org.apache.avalon.cornerstone.services.store.Store;
import org.apache.avalon.cornerstone.services.store.StreamRepository;
import org.apache.avalon.cornerstone.services.datasource.DataSourceSelector;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.phoenix.BlockContext;
import org.apache.james.core.MimeMessageWrapper;
import org.apache.james.core.MailImpl;
import org.apache.james.services.MailRepository;
import org.apache.james.services.SpoolRepository;
import org.apache.james.util.Lock;
import org.apache.james.util.SqlResources;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
// Sam. Oracle code implementation of BLOB binary type.
// Need to import oracle sql packages.
// START
//needed for new CLOB and BLOB classes
import oracle.sql.*;
import oracle.jdbc.driver.*;
// END
/**
* Implementation of a MailRepository on a database.
*
* <p>Requires a configuration element in the .conf.xml file of the form:
* <br><repository
destinationURL="db://<datasource>/<table_name>/<repository_name>"
* <br> type="MAIL"
* <br> model="SYNCHRONOUS"/>
* <br></repository>
* <p>destinationURL specifies..(Serge??)
* <br>Type can be SPOOL or MAIL
* <br>Model is currently not used and may be dropped
*
* <p>Requires a logger called MailRepository.
*
* @author Serge Knystautas <[EMAIL PROTECTED]>
* @author Darrell DeBoer <[EMAIL PROTECTED]>
* @version 1.0.0, 24/04/1999
*/
public class JDBCMailRepository
extends AbstractLoggable
implements MailRepository, Component, Contextualizable, Composable,
Configurable, Initializable {
protected Context context;
private Lock lock;
// Configuration elements
protected String destination;
protected String tableName;
protected String repositoryName;
protected String filestore;
protected String sqlFileName;
private StreamRepository sr = null;
//The data-source for this repository
protected DataSourceSelector datasources;
protected DataSourceComponent datasource;
protected String datasourceName;
// Contains all of the sql strings for this component.
protected SqlResources sqlQueries;
public void contextualize(final Context context)
throws ContextException {
this.context = context;
}
public void configure(Configuration conf) throws ConfigurationException
{
getLogger().debug(this.getClass().getName() + ".configure()");
destination = conf.getAttribute("destinationURL");
// normalise the destination, to simplify processing.
if ( ! destination.endsWith("/") ) {
destination += "/";
}
// Parse the DestinationURL for the name of the datasource,
// the table to use, and the (optional) repository Key.
// Split on "/", starting after "db://"
List urlParams = new ArrayList();
int start = 5;
if (destination.startsWith("dbfile")) {
//this is dbfile:// instead of db://
start += 4;
}
int end = destination.indexOf('/', start);
while ( end > -1 ) {
urlParams.add(destination.substring(start, end));
start = end + 1;
end = destination.indexOf('/', start);
}
// Build SqlParameters and get datasource name from URL parameters
if (urlParams.size() == 0) {
throw new ConfigurationException
("Malformed destinationURL - Must be of the format '" +
"db://<data-source>[/<table>[/<repositoryName>]]'. Was
passed " + conf.getAttribute("destinationURL"));
}
if (urlParams.size() >= 1) {
datasourceName = (String)urlParams.get(0);
}
if (urlParams.size() >= 2) {
tableName = (String)urlParams.get(1);
}
if (urlParams.size() >= 3) {
repositoryName = "";
for (int i = 2; i < urlParams.size(); i++) {
if (i >= 3) {
repositoryName += '/';
}
repositoryName += (String)urlParams.get(i);
}
}
getLogger().debug("Parsed URL: table = '" + tableName +
"', repositoryName = '" + repositoryName + "'");
filestore = conf.getChild("filestore").getValue(null);
sqlFileName = conf.getChild("sqlFile").getValue();
if (!sqlFileName.startsWith("file://")) {
throw new ConfigurationException
("Malformed sqlFile - Must be of the format
'file://<filename>'.");
}
}
public void compose( final ComponentManager componentManager )
throws ComponentException {
getLogger().debug(this.getClass().getName() + ".compose()");
// Get the DataSourceSelector block
datasources = (DataSourceSelector)componentManager.lookup(
DataSourceSelector.ROLE );
try {
if (filestore != null) {
Store store = (Store)componentManager.
lookup("org.apache.avalon.cornerstone.services.store.Store");
//prepare Configurations for stream repositories
DefaultConfiguration streamConfiguration
= new DefaultConfiguration( "repository",
"generated:JDBCMailRepository.compose()" );
streamConfiguration.setAttribute( "destinationURL",
filestore );
streamConfiguration.setAttribute( "type", "STREAM" );
streamConfiguration.setAttribute( "model", "SYNCHRONOUS" );
sr = (StreamRepository) store.select(streamConfiguration);
getLogger().debug("Got filestore for JdbcMailRepository: " +
filestore);
}
lock = new Lock();
getLogger().debug(this.getClass().getName() + " created
according to " + destination);
} catch (Exception e) {
final String message = "Failed to retrieve Store component:" +
e.getMessage();
getLogger().error(message, e);
e.printStackTrace();
throw new ComponentException(message, e);
}
}
/**
* Initialises the JDBC repository.
* 1) Tests the connection to the database.
* 2) Loads SQL strings from the SQL definition file,
* choosing the appropriate SQL for this connection,
* and performing paramter substitution,
* 3) Initialises the database with the required tables, if necessary.
*
*/
public void initialize() throws Exception {
getLogger().debug(this.getClass().getName() + ".initialize()");
// Sam. Oracle code implementation of BLOB binary type
// START
// Register the Oracle JDBC driver
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
// END
// Get the data-source required.
datasource =
(DataSourceComponent)datasources.select(datasourceName);
// Test the connection to the database, by getting the
DatabaseMetaData.
Connection conn = datasource.getConnection();
try {
// Initialise the sql strings.
String fileName = sqlFileName.substring("file://".length());
fileName = ((BlockContext)context).getBaseDirectory() +
File.separator + fileName;
File sqlFile = (new File(fileName)).getCanonicalFile();
String resourceName =
"org.apache.james.mailrepository.JDBCMailRepository";
getLogger().debug("Reading SQL resources from file: " +
sqlFile.getAbsolutePath() + ", section " +
this.getClass().getName() + ".");
// Build the statement parameters
Map sqlParameters = new HashMap();
if (tableName != null) {
sqlParameters.put("table", tableName);
}
if (repositoryName != null) {
sqlParameters.put("repository", repositoryName);
}
sqlQueries = new SqlResources();
sqlQueries.init(sqlFile, this.getClass().getName(),
conn, sqlParameters);
// Check if the required table exists. If not, create it.
DatabaseMetaData dbMetaData = conn.getMetaData();
// Need to ask in the case that identifiers are stored, ask the
DatabaseMetaInfo.
// Try UPPER, lower, and MixedCase, to see if the table is
there.
if (! ( tableExists(dbMetaData, tableName) ||
tableExists(dbMetaData, tableName.toUpperCase()) ||
tableExists(dbMetaData, tableName.toLowerCase()) )) {
// Users table doesn't exist - create it.
PreparedStatement createStatement =
conn.prepareStatement(sqlQueries.getSqlString("createTable", true));
createStatement.execute();
createStatement.close();
getLogger().info("JdbcMailRepository: Created table '" +
tableName + "'.");
}
} finally {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private boolean tableExists(DatabaseMetaData dbMetaData, String
tableName)
throws SQLException {
ResultSet rsTables = dbMetaData.getTables(null, null, tableName,
null);
boolean found = rsTables.next();
rsTables.close();
return found;
}
public synchronized boolean unlock(String key) {
if (lock.unlock(key)) {
notifyAll();
return true;
} else {
return false;
}
}
public synchronized boolean lock(String key) {
if (lock.lock(key)) {
//notifyAll();
return true;
} else {
return false;
}
}
public void store(MailImpl mc) {
//System.err.println("storing " + mc.getName());
Connection conn = null;
try {
conn = datasource.getConnection();
//Need to determine whether need to insert this record, or
update it.
//Begin a transaction
conn.setAutoCommit(false);
PreparedStatement checkMessageExists =
conn.prepareStatement(sqlQueries.getSqlString("checkMessageExistsSQL",
true));
checkMessageExists.setString(1, mc.getName());
checkMessageExists.setString(2, repositoryName);
ResultSet rsExists = checkMessageExists.executeQuery();
boolean exists = rsExists.next() && rsExists.getInt(1) > 0;
rsExists.close();
checkMessageExists.close();
if (exists) {
//Update the existing record
PreparedStatement updateMessage =
conn.prepareStatement(sqlQueries.getSqlString("updateMessageSQL", true));
updateMessage.setString(1, mc.getState());
updateMessage.setString(2, mc.getErrorMessage());
if (mc.getSender() == null) {
updateMessage.setNull(3, java.sql.Types.VARCHAR);
} else {
updateMessage.setString(3, mc.getSender().toString());
}
StringBuffer recipients = new StringBuffer();
for (Iterator i = mc.getRecipients().iterator();
i.hasNext(); ) {
recipients.append(i.next().toString());
if (i.hasNext()) {
recipients.append("\r\n");
}
}
updateMessage.setString(4, recipients.toString());
updateMessage.setString(5, mc.getRemoteHost());
updateMessage.setString(6, mc.getRemoteAddr());
updateMessage.setTimestamp(7, new
java.sql.Timestamp(mc.getLastUpdated().getTime()));
updateMessage.setString(8, mc.getName());
updateMessage.setString(9, repositoryName);
updateMessage.execute();
updateMessage.close();
//Determine whether the message body has changed, and
possibly avoid
// updating the database.
MimeMessage messageBody = mc.getMessage();
boolean saveBody = false;
if (messageBody instanceof MimeMessageWrapper) {
MimeMessageWrapper message =
(MimeMessageWrapper)messageBody;
saveBody = message.isModified();
} else {
saveBody = true;
}
if (saveBody) {
// Sam. Oracle code implementation of BLOB binary type
// START
/*updateMessage =
conn.prepareStatement(sqlQueries.getSqlString("updateMessageBodySQL",
true));*/
// Must first retrieve BLOB locator for message_body
field
// in Oracle database prior to value insertion.
PreparedStatement readMessageBody =
conn.prepareStatement(sqlQueries.getSqlString("retrieveMessageBodySQL",
true));
readMessageBody.setString(1, mc.getName());
readMessageBody.setString(2, repositoryName);
ResultSet rset = readMessageBody.executeQuery();
if (rset.next())
{
// retrieve the LOB locator from the ResultSet
BLOB messageBody_blob =
((OracleResultSet)rset).getBLOB(1);
OraclePreparedStatement ops =
(OraclePreparedStatement) conn.prepareStatement(
sqlQueries.getSqlString("updateMessageBodySQL",
true));
// END
ByteArrayOutputStream headerOut = new
ByteArrayOutputStream();
OutputStream bodyOut = null;
if (sr == null) {
//If there is no filestore, use the byte array to
store headers
// and the body
bodyOut = headerOut;
} else {
//Store the body in the stream repository
bodyOut = sr.put(mc.getName());
}
//Write the message to the headerOut and bodyOut.
bodyOut goes straight to the file
MimeMessageWrapper.writeTo(messageBody, headerOut,
bodyOut);
bodyOut.close();
//Store the headers in the database
// Sam. Oracle code implementation of BLOB binary type
// START
// Start writing to the start of the LOB. ie.
overwrite.
// Write the contents of the buffer into position pos
of the output LOB:
messageBody_blob.putBytes(0, headerOut.toByteArray());
ops.setBlob(1, messageBody_blob);
ops.setString(2, mc.getName());
ops.setString(3, repositoryName);
ops.execute();
ops.close();
} // End if {rset.next()}
readMessageBody.close();
rset.close();
// END
}
} else {
//Insert the record into the database
// Sam. Oracle code implementation of BLOB binary type
// START
/*PreparedStatement insertMessage =
conn.prepareStatement(sqlQueries.getSqlString("insertMessageSQL", true));*/
OraclePreparedStatement insertMessage =
(OraclePreparedStatement) conn.prepareStatement(
sqlQueries.getSqlString("insertMessageSQL", true));
// END
insertMessage.setString(1, mc.getName());
insertMessage.setString(2, repositoryName);
insertMessage.setString(3, mc.getState());
insertMessage.setString(4, mc.getErrorMessage());
if (mc.getSender() == null) {
insertMessage.setNull(5, java.sql.Types.VARCHAR);
} else {
insertMessage.setString(5, mc.getSender().toString());
}
StringBuffer recipients = new StringBuffer();
for (Iterator i = mc.getRecipients().iterator();
i.hasNext(); ) {
recipients.append(i.next().toString());
if (i.hasNext()) {
recipients.append("\r\n");
}
}
insertMessage.setString(6, recipients.toString());
insertMessage.setString(7, mc.getRemoteHost());
insertMessage.setString(8, mc.getRemoteAddr());
insertMessage.setTimestamp(9, new
java.sql.Timestamp(mc.getLastUpdated().getTime()));
MimeMessage messageBody = mc.getMessage();
ByteArrayOutputStream headerOut = new
ByteArrayOutputStream();
OutputStream bodyOut = null;
if (sr == null) {
//If there is no sr, then use the same byte array to
hold the headers
// and the body
bodyOut = headerOut;
} else {
//Store the body in the file system.
bodyOut = sr.put(mc.getName());
}
//Write the message to the headerOut and bodyOut. bodyOut
goes straight to the file
MimeMessageWrapper.writeTo(messageBody, headerOut, bodyOut);
bodyOut.close();
//Store the headers in the database
// Sam. Oracle code implementation of BLOB binary type
// START
//insertMessage.setBytes(10, headerOut.toByteArray());
insertMessage.setObject(10, headerOut.toByteArray());
insertMessage.execute();
insertMessage.close();
// END
} // End if {(exists)}
conn.commit();
conn.setAutoCommit(true);
synchronized (this) {
notifyAll();
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Exception caught while storing mail
Container: " + e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqle) {
//ignore
}
}
}
}
public MailImpl retrieve(String key) {
//System.err.println("retrieving " + key);
Connection conn = null;
try {
conn = datasource.getConnection();
PreparedStatement retrieveMessage =
conn.prepareStatement(sqlQueries.getSqlString("retrieveMessageSQL", true));
retrieveMessage.setString(1, key);
retrieveMessage.setString(2, repositoryName);
ResultSet rsMessage = retrieveMessage.executeQuery();
if (!rsMessage.next()) {
throw new RuntimeException("Did not find a record " + key +
" in " + repositoryName);
}
MailImpl mc = new MailImpl();
mc.setName(key);
mc.setState(rsMessage.getString(1));
mc.setErrorMessage(rsMessage.getString(2));
String sender = rsMessage.getString(3);
if (sender == null) {
mc.setSender(null);
} else {
mc.setSender(new MailAddress(sender));
}
StringTokenizer st = new StringTokenizer(rsMessage.getString(4),
"\r\n", false);
Set recipients = new HashSet();
while (st.hasMoreTokens()) {
recipients.add(new MailAddress(st.nextToken()));
}
mc.setRecipients(recipients);
mc.setRemoteHost(rsMessage.getString(5));
mc.setRemoteAddr(rsMessage.getString(6));
mc.setLastUpdated(rsMessage.getTimestamp(7));
MimeMessageJDBCSource source = new MimeMessageJDBCSource(this,
key, sr);
MimeMessageWrapper message = new MimeMessageWrapper(source);
mc.setMessage(message);
rsMessage.close();
retrieveMessage.close();
return mc;
} catch (SQLException sqle) {
synchronized (System.err) {
System.err.println("Error retrieving message");
System.err.println(sqle.getMessage());
System.err.println(sqle.getErrorCode());
System.err.println(sqle.getSQLState());
System.err.println(sqle.getNextException());
sqle.printStackTrace();
}
throw new RuntimeException("Exception while retrieving mail: " +
sqle.getMessage());
} catch (Exception me) {
me.printStackTrace();
throw new RuntimeException("Exception while retrieving mail: " +
me.getMessage());
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqle) {
//ignore
}
}
}
}
public void remove(MailImpl mail) {
remove(mail.getName());
}
public void remove(String key) {
//System.err.println("removing " + key);
if (lock(key)) {
Connection conn = null;
try {
conn = datasource.getConnection();
PreparedStatement removeMessage =
conn.prepareStatement(sqlQueries.getSqlString("removeMessageSQL", true));
removeMessage.setString(1, key);
removeMessage.setString(2, repositoryName);
removeMessage.execute();
removeMessage.close();
if (sr != null) {
sr.remove(key);
}
} catch (Exception me) {
throw new RuntimeException("Exception while removing mail: "
+ me.getMessage());
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqle) {
//ignore
}
}
unlock(key);
}
}
}
public Iterator list() {
//System.err.println("listing messages");
Connection conn = null;
try {
conn = datasource.getConnection();
PreparedStatement listMessages =
conn.prepareStatement(sqlQueries.getSqlString("listMessagesSQL", true));
listMessages.setString(1, repositoryName);
ResultSet rsListMessages = listMessages.executeQuery();
List messageList = new ArrayList();
while (rsListMessages.next()) {
messageList.add(rsListMessages.getString(1));
}
rsListMessages.close();
listMessages.close();
return messageList.iterator();
} catch (Exception me) {
me.printStackTrace();
throw new RuntimeException("Exception while listing mail: " +
me.getMessage());
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqle) {
//ignore
}
}
}
}
protected Connection getConnection() throws SQLException {
return datasource.getConnection();
}
public boolean equals(Object obj) {
if (!(obj instanceof JDBCMailRepository)) {
return false;
}
JDBCMailRepository repository = (JDBCMailRepository)obj;
return repository.tableName.equals(tableName) &&
repository.repositoryName.equals(repositoryName);
}
}
Second, here's the code for MimeMessageJDBCSource:
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.james.mailrepository;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.james.core.MimeMessageSource;
import org.apache.avalon.cornerstone.services.store.StreamRepository;
import org.apache.james.util.SqlResources;
import java.lang.Long;
// Sam. Oracle code implementation of BLOB binary type
// Need to import oracle sql packages.
// START
//needed for new CLOB and BLOB classes
import oracle.sql.*;
import oracle.jdbc.driver.*;
// END
/**
* This class points to a specific message in a repository. This will return
an
* InputStream to the JDBC field/record, possibly sequenced with the file
stream.
*/
public class MimeMessageJDBCSource extends MimeMessageSource {
//Define how to get to the data
JDBCMailRepository repository = null;
String key = null;
StreamRepository sr = null;
String retrieveMessageBodySQL = null;
String retrieveMessageBodySizeSQL = null;
/**
* Construct a MimeMessageSource based on a JDBC repository, a key, and
a
* stream repository (where we might store the message body)
*/
public MimeMessageJDBCSource(JDBCMailRepository repository,
String key, StreamRepository sr) throws IOException {
if (repository == null) {
throw new IOException("Repository is null");
}
if (key == null) {
throw new IOException("Message name (key) was not defined");
}
this.repository = repository;
this.key = key;
this.sr = sr;
// Sam. Oracle code implementation of BLOB binary type
// START
try
{
// Register the Oracle JDBC driver
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
}
catch (Exception e)
{
e.printStackTrace();
}
// END
retrieveMessageBodySQL =
repository.sqlQueries.getSqlString("retrieveMessageBodySQL",
true);
// this is optional
retrieveMessageBodySizeSQL =
repository.sqlQueries.getSqlString("retrieveMessageBodySizeSQL");
}
/**
* Return the input stream to the database field and then the file
stream. This should
* be smart enough to work even if the file does not exist. This is to
support
* a repository with the entire message in the database, which is how
James 1.2 worked.
*/
public synchronized InputStream getInputStream() throws IOException {
try {
Connection conn = repository.getConnection();
PreparedStatement retrieveMessageStream =
conn.prepareStatement(retrieveMessageBodySQL);
retrieveMessageStream.setString(1, key);
retrieveMessageStream.setString(2, repository.repositoryName);
ResultSet rsRetrieveMessageStream =
retrieveMessageStream.executeQuery();
if (!rsRetrieveMessageStream.next()) {
throw new IOException("Could not find message");
}
// Sam. Oracle code implementation of BLOB binary type
// START
// retrieve the LOB locator from the ResultSet
BLOB messageBody_blob =
((OracleResultSet)rsRetrieveMessageStream).getBLOB(1);
// read the blob into a byte array
Long lval = new Long(messageBody_blob.length());
//byte[] headers = rsRetrieveMessageStream.getBytes(1);
byte[] headers = messageBody_blob.getBytes(1, lval.intValue());
// END
rsRetrieveMessageStream.close();
retrieveMessageStream.close();
conn.close();
InputStream in = new ByteArrayInputStream(headers);
try {
if (sr != null) {
in = new SequenceInputStream(in, sr.get(key));
}
} catch (Exception e) {
//ignore this... either sr is null, or the file does not
exist
// or something else
}
return in;
} catch (SQLException sqle) {
throw new IOException(sqle.toString());
}
}
/**
* Runs a custom SQL statement to check the size of the message body
*/
public synchronized long getMessageSize() throws IOException {
if (retrieveMessageBodySizeSQL == null) {
//There was no SQL statement for this repository... figure it
out the hard way
return super.getMessageSize();
}
try {
Connection conn = repository.getConnection();
PreparedStatement retrieveMessageSize =
conn.prepareStatement(retrieveMessageBodySizeSQL);
retrieveMessageSize.setString(1, key);
retrieveMessageSize.setString(2, repository.repositoryName);
ResultSet rsRetrieveMessageSize =
retrieveMessageSize.executeQuery();
if (!rsRetrieveMessageSize.next()) {
throw new IOException("Could not find message");
}
long size = rsRetrieveMessageSize.getLong(1);
rsRetrieveMessageSize.close();
retrieveMessageSize.close();
conn.close();
try {
if (sr != null) {
InputStream in = sr.get(key);
int len = 0;
byte[] block = new byte[1024];
while ((len = in.read(block)) > -1) {
size += len;
}
in.close();
}
} catch (Exception e) {
//ignore this... either sr is null, or the file does not
exist
// or something else
}
return size;
} catch (SQLException sqle) {
throw new IOException(sqle.toString());
}
}
/**
* Check to see whether this is the same repository and the same key
*/
public boolean equals(Object obj) {
if (obj instanceof MimeMessageJDBCSource) {
MimeMessageJDBCSource source = (MimeMessageJDBCSource)obj;
return source.key.equals(key) &&
source.repository.equals(repository);
}
return false;
}
}
Also, you'll need to place the two oracle classes I mentioned to you into
the lib directory of James installation.
And that is it!
Please incorporate the following credits to the effected sources which I
myself have implemented into the next release of James:
@author Samuel Sadek <[EMAIL PROTECTED], [EMAIL PROTECTED],
[EMAIL PROTECTED]>
Thank you.
One word of note, Serge, there are several versions of Oracle out there,
need to provide in next release of James, potential set of Oracle JDBC
driver classes, especially if it has changed for Oracle 9i.
>Sorry, I should have been clearer. Can you provide the Oracle workaround
>to
>support a BINARY LOB? We can, but I'd prefer to not apply the text-based
>shortcut because I expect it will cause other users problems by corrupting
>their messages.
>Serge Knystautas
>Loki Technologies - Unstoppable Websites
>http://www.lokitech.com/
----- Original Message -----
From: "Samuel Sadek" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Sunday, February 24, 2002 7:32 PM
Subject: Re: How to make James work with Oracle database?
>Serge,
>
>The class is JamesJDBCMailRepository in method (public void store(MailImpl
>mc)):
>
>Scan for the start/end markers to find modified code. Remember I just
simply
>copied the contents of the byte array output into a string and written
this
>directly via setString into the message_body field within inbox table in
>Oracle 8.1.7.
_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>