JDBCMailRepositorypublic class JDBCMailRepository extends org.apache.avalon.framework.logger.AbstractLogEnabled implements org.apache.avalon.framework.service.Serviceable, org.apache.avalon.framework.activity.Initializable, org.apache.avalon.framework.context.Contextualizable, org.apache.avalon.framework.configuration.Configurable, org.apache.james.services.MailRepositoryImplementation of a MailRepository on a database.
Requires a configuration element in the .conf.xml file of the form:
<repository destinationURL="db://<datasource>/<table_name>/<repository_name>"
type="MAIL"
model="SYNCHRONOUS"/>
</repository>
destinationURL specifies..(Serge??)
Type can be SPOOL or MAIL
Model is currently not used and may be dropped
Requires a logger called MailRepository. |
Fields Summary |
---|
private static final boolean | DEEP_DEBUGWhether 'deep debugging' is turned on. | private org.apache.avalon.framework.service.ServiceManager | componentManagerThe Avalon componentManager used by the instance | protected org.apache.avalon.framework.context.Context | contextThe Avalon context used by the instance | private org.apache.james.util.Lock | lockA lock used to control access to repository elements, locking access
based on the key | protected String | tableNameThe table name parsed from the destination URL | protected String | repositoryNameThe repository name parsed from the destination URL | private String | sqlFileNameThe name of the SQL configuration file to be used to configure this repository. | private org.apache.avalon.cornerstone.services.store.StreamRepository | srThe stream repository used in dbfile mode | protected org.apache.avalon.cornerstone.services.datasources.DataSourceSelector | datasourcesThe selector used to obtain the JDBC datasource | protected org.apache.avalon.excalibur.datasource.DataSourceComponent | datasourceThe JDBC datasource that provides the JDBC connection | protected String | datasourceNameThe name of the datasource used by this repository | protected org.apache.james.util.SqlResources | sqlQueriesContains all of the sql strings for this component. | protected org.apache.james.util.JDBCUtil | theJDBCUtilThe JDBCUtil helper class | protected boolean | jdbcMailAttributesReady"Support for Mail Attributes under JDBC repositories is ready" indicator. | private int | inMemorySizeLimitThe size threshold for in memory handling of storing operations |
Methods Summary |
---|
protected void | checkJdbcAttributesSupport(java.sql.DatabaseMetaData dbMetaData)Checks whether support for JDBC Mail atributes is activated for this repository
and if everything is consistent.
Looks for both the "updateMessageAttributesSQL" and "retrieveMessageAttributesSQL"
statements in sqlResources and for a table column named "message_attributes".
String attributesColumnName = "message_attributes";
boolean hasUpdateMessageAttributesSQL = false;
boolean hasRetrieveMessageAttributesSQL = false;
boolean hasMessageAttributesColumn = theJDBCUtil.columnExists(dbMetaData, tableName, attributesColumnName);
StringBuffer logBuffer = new StringBuffer(64)
.append("JdbcMailRepository '"
+ repositoryName
+ ", table '"
+ tableName
+ "': ");
//Determine whether attributes are used and available for storing
//Do we have updateMessageAttributesSQL?
String updateMessageAttrSql =
sqlQueries.getSqlString("updateMessageAttributesSQL", false);
if (updateMessageAttrSql!=null) {
hasUpdateMessageAttributesSQL = true;
}
//Determine whether attributes are used and retrieve them
//Do we have retrieveAttributesSQL?
String retrieveMessageAttrSql =
sqlQueries.getSqlString("retrieveMessageAttributesSQL", false);
if (retrieveMessageAttrSql!=null) {
hasRetrieveMessageAttributesSQL = true;
}
if (hasUpdateMessageAttributesSQL && !hasRetrieveMessageAttributesSQL) {
logBuffer.append("JDBC Mail Attributes support was activated for update but not for retrieval"
+ "(found 'updateMessageAttributesSQL' but not 'retrieveMessageAttributesSQL'"
+ "in table '"
+ tableName
+ "').");
getLogger().fatalError(logBuffer.toString());
throw new SQLException(logBuffer.toString());
}
if (!hasUpdateMessageAttributesSQL && hasRetrieveMessageAttributesSQL) {
logBuffer.append("JDBC Mail Attributes support was activated for retrieval but not for update"
+ "(found 'retrieveMessageAttributesSQL' but not 'updateMessageAttributesSQL'"
+ "in table '"
+ tableName
+ "'.");
getLogger().fatalError(logBuffer.toString());
throw new SQLException(logBuffer.toString());
}
if (!hasMessageAttributesColumn
&& (hasUpdateMessageAttributesSQL || hasRetrieveMessageAttributesSQL)
) {
logBuffer.append("JDBC Mail Attributes support was activated but column '"
+ attributesColumnName
+ "' is missing in table '"
+ tableName
+ "'.");
getLogger().fatalError(logBuffer.toString());
throw new SQLException(logBuffer.toString());
}
if (hasUpdateMessageAttributesSQL && hasRetrieveMessageAttributesSQL) {
jdbcMailAttributesReady = true;
if (getLogger().isInfoEnabled()) {
logBuffer.append("JDBC Mail Attributes support ready.");
getLogger().info(logBuffer.toString());
}
} else {
jdbcMailAttributesReady = false;
logBuffer.append("JDBC Mail Attributes support not activated. "
+ "Missing both 'updateMessageAttributesSQL' "
+ "and 'retrieveMessageAttributesSQL' "
+ "statements for table '"
+ tableName
+ "' in sqlResources.xml. "
+ "Will not persist in the repository '"
+ repositoryName
+ "'.");
getLogger().warn(logBuffer.toString());
}
| public void | configure(org.apache.avalon.framework.configuration.Configuration conf)
if (getLogger().isDebugEnabled()) {
getLogger().debug(this.getClass().getName() + ".configure()");
}
String destination = conf.getAttribute("destinationURL");
// normalize 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) {
StringBuffer exceptionBuffer =
new StringBuffer(256)
.append("Malformed destinationURL - Must be of the format '")
.append("db://<data-source>[/<table>[/<repositoryName>]]'. Was passed ")
.append(conf.getAttribute("destinationURL"));
throw new ConfigurationException(exceptionBuffer.toString());
}
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);
}
}
if (getLogger().isDebugEnabled()) {
StringBuffer logBuffer =
new StringBuffer(128)
.append("Parsed URL: table = '")
.append(tableName)
.append("', repositoryName = '")
.append(repositoryName)
.append("'");
getLogger().debug(logBuffer.toString());
}
inMemorySizeLimit = conf.getChild("inMemorySizeLimit").getValueAsInteger(409600000);
String 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>'.");
}
try {
if (filestore != null) {
Store store = (Store)componentManager.lookup(Store.ROLE);
//prepare Configurations for stream repositories
DefaultConfiguration streamConfiguration
= new DefaultConfiguration( "repository",
"generated:JDBCMailRepository.configure()" );
streamConfiguration.setAttribute( "destinationURL", filestore );
streamConfiguration.setAttribute( "type", "STREAM" );
streamConfiguration.setAttribute( "model", "SYNCHRONOUS" );
sr = (StreamRepository) store.select(streamConfiguration);
if (getLogger().isDebugEnabled()) {
getLogger().debug("Got filestore for JdbcMailRepository: " + filestore);
}
}
lock = new Lock();
if (getLogger().isDebugEnabled()) {
StringBuffer logBuffer =
new StringBuffer(128)
.append(this.getClass().getName())
.append(" created according to ")
.append(destination);
getLogger().debug(logBuffer.toString());
}
} catch (Exception e) {
final String message = "Failed to retrieve Store component:" + e.getMessage();
getLogger().error(message, e);
throw new ConfigurationException(message, e);
}
| public void | contextualize(org.apache.avalon.framework.context.Context context)
this.context = context;
| public boolean | equals(java.lang.Object obj)
if (!(obj instanceof JDBCMailRepository)) {
return false;
}
// TODO: Figure out whether other instance variables should be part of
// the equals equation
JDBCMailRepository repository = (JDBCMailRepository)obj;
return ((repository.tableName == tableName) || ((repository.tableName != null) && repository.tableName.equals(tableName))) &&
((repository.repositoryName == repositoryName) || ((repository.repositoryName != null) && repository.repositoryName.equals(repositoryName)));
| protected java.sql.Connection | getConnection()Gets the SQL connection to be used by this JDBCMailRepository
return datasource.getConnection();
| private int | getNumberOfParameters(java.lang.String sqlstring)This method calculates number of parameters in a prepared statement SQL String.
It does so by counting the number of '?' in the string
//it is alas a java 1.4 feature to be able to call
//getParameterMetaData which could provide us with the parameterCount
char[] chars = sqlstring.toCharArray();
int count = 0;
for (int i = 0; i < chars.length; i++) {
count += chars[i]=='?" ? 1 : 0;
}
return count;
| public int | hashCode()Provide a hash code that is consistent with equals for this class
int result = 17;
if (tableName != null) {
result = 37 * tableName.hashCode();
}
if (repositoryName != null) {
result = 37 * repositoryName.hashCode();
}
return result;
| public void | initialize()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.
StringBuffer logBuffer = null;
if (getLogger().isDebugEnabled()) {
getLogger().debug(this.getClass().getName() + ".initialize()");
}
theJDBCUtil =
new JDBCUtil() {
protected void delegatedLog(String logString) {
JDBCMailRepository.this.getLogger().warn("JDBCMailRepository: " + logString);
}
};
// Get the data-source required.
datasource = (DataSourceComponent)datasources.select(datasourceName);
// Test the connection to the database, by getting the DatabaseMetaData.
Connection conn = datasource.getConnection();
PreparedStatement createStatement = null;
try {
// Initialise the sql strings.
File sqlFile = null;
try {
sqlFile = AvalonContextUtilities.getFile(context, sqlFileName);
sqlFileName = null;
} catch (Exception e) {
getLogger().fatalError(e.getMessage(), e);
throw e;
}
if (getLogger().isDebugEnabled()) {
logBuffer =
new StringBuffer(128)
.append("Reading SQL resources from file: ")
.append(sqlFile.getAbsolutePath())
.append(", section ")
.append(this.getClass().getName())
.append(".");
getLogger().debug(logBuffer.toString());
}
// 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 (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
// Users table doesn't exist - create it.
createStatement =
conn.prepareStatement(sqlQueries.getSqlString("createTable", true));
createStatement.execute();
if (getLogger().isInfoEnabled()) {
logBuffer =
new StringBuffer(64)
.append("JdbcMailRepository: Created table '")
.append(tableName)
.append("'.");
getLogger().info(logBuffer.toString());
}
}
checkJdbcAttributesSupport(dbMetaData);
} finally {
theJDBCUtil.closeJDBCStatement(createStatement);
theJDBCUtil.closeJDBCConnection(conn);
}
| public java.util.Iterator | list()Gets a list of message keys stored in this repository.
//System.err.println("listing messages");
Connection conn = null;
PreparedStatement listMessages = null;
ResultSet rsListMessages = null;
try {
conn = datasource.getConnection();
listMessages =
conn.prepareStatement(sqlQueries.getSqlString("listMessagesSQL", true));
listMessages.setString(1, repositoryName);
rsListMessages = listMessages.executeQuery();
List messageList = new ArrayList();
while (rsListMessages.next() && !Thread.currentThread().isInterrupted()) {
messageList.add(rsListMessages.getString(1));
}
return messageList.iterator();
} catch (Exception me) {
throw new MessagingException("Exception while listing mail: " + me.getMessage());
} finally {
theJDBCUtil.closeJDBCResultSet(rsListMessages);
theJDBCUtil.closeJDBCStatement(listMessages);
theJDBCUtil.closeJDBCConnection(conn);
}
| public boolean | lock(java.lang.String key)Obtains a lock on a message identified by a key
if (lock.lock(key)) {
if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
StringBuffer debugBuffer =
new StringBuffer(256)
.append("Locked ")
.append(key)
.append(" for ")
.append(Thread.currentThread().getName())
.append(" @ ")
.append(new java.util.Date(System.currentTimeMillis()));
getLogger().debug(debugBuffer.toString());
}
return true;
} else {
return false;
}
| public void | remove(org.apache.mailet.Mail mail)Removes a specified message
remove(mail.getName());
| public void | remove(java.util.Collection mails)Removes a Collection of mails from the repository
Iterator delList = mails.iterator();
while (delList.hasNext()) {
remove((Mail)delList.next());
}
| public void | remove(java.lang.String key)Removes a message identified by a key.
//System.err.println("removing " + key);
if (lock(key)) {
Connection conn = null;
PreparedStatement removeMessage = null;
try {
conn = datasource.getConnection();
removeMessage =
conn.prepareStatement(sqlQueries.getSqlString("removeMessageSQL", true));
removeMessage.setString(1, key);
removeMessage.setString(2, repositoryName);
removeMessage.execute();
if (sr != null) {
sr.remove(key);
}
} catch (Exception me) {
throw new MessagingException("Exception while removing mail: " + me.getMessage());
} finally {
theJDBCUtil.closeJDBCStatement(removeMessage);
theJDBCUtil.closeJDBCConnection(conn);
unlock(key);
}
}
| public org.apache.mailet.Mail | retrieve(java.lang.String key)Retrieves a message given a key. At the moment, keys can be obtained
from list()
if (DEEP_DEBUG) {
System.err.println("retrieving " + key);
}
Connection conn = null;
PreparedStatement retrieveMessage = null;
ResultSet rsMessage = null;
try {
conn = datasource.getConnection();
if (DEEP_DEBUG) {
System.err.println("got a conn " + key);
}
retrieveMessage =
conn.prepareStatement(sqlQueries.getSqlString("retrieveMessageSQL", true));
retrieveMessage.setString(1, key);
retrieveMessage.setString(2, repositoryName);
rsMessage = retrieveMessage.executeQuery();
if (DEEP_DEBUG) {
System.err.println("ran the query " + key);
}
if (!rsMessage.next()) {
if (getLogger().isDebugEnabled()) {
StringBuffer debugBuffer =
new StringBuffer(64)
.append("Did not find a record ")
.append(key)
.append(" in ")
.append(repositoryName);
getLogger().debug(debugBuffer.toString());
}
return null;
}
//Determine whether attributes are used and retrieve them
PreparedStatement retrieveMessageAttr = null;
HashMap attributes = null;
if (jdbcMailAttributesReady) {
String retrieveMessageAttrSql =
sqlQueries.getSqlString("retrieveMessageAttributesSQL", false);
ResultSet rsMessageAttr = null;
try {
retrieveMessageAttr =
conn.prepareStatement(retrieveMessageAttrSql);
retrieveMessageAttr.setString(1, key);
retrieveMessageAttr.setString(2, repositoryName);
rsMessageAttr = retrieveMessageAttr.executeQuery();
if (rsMessageAttr.next()) {
try {
byte[] serialized_attr = null;
String getAttributesOption = sqlQueries.getDbOption("getAttributes");
if (getAttributesOption != null && (getAttributesOption.equalsIgnoreCase("useBlob") || getAttributesOption.equalsIgnoreCase("useBinaryStream"))) {
Blob b = rsMessageAttr.getBlob(1);
serialized_attr = b.getBytes(1, (int)b.length());
} else {
serialized_attr = rsMessageAttr.getBytes(1);
}
// this check is for better backwards compatibility
if (serialized_attr != null) {
ByteArrayInputStream bais = new ByteArrayInputStream(serialized_attr);
ObjectInputStream ois = new ObjectInputStream(bais);
attributes = (HashMap)ois.readObject();
ois.close();
}
} catch (IOException ioe) {
if (getLogger().isDebugEnabled()) {
StringBuffer debugBuffer =
new StringBuffer(64)
.append("Exception reading attributes ")
.append(key)
.append(" in ")
.append(repositoryName);
getLogger().debug(debugBuffer.toString(), ioe);
}
}
} else {
if (getLogger().isDebugEnabled()) {
StringBuffer debugBuffer =
new StringBuffer(64)
.append("Did not find a record (attributes) ")
.append(key)
.append(" in ")
.append(repositoryName);
getLogger().debug(debugBuffer.toString());
}
}
} catch (SQLException sqle) {
StringBuffer errorBuffer = new StringBuffer(256)
.append("Error retrieving message")
.append(sqle.getMessage())
.append(sqle.getErrorCode())
.append(sqle.getSQLState())
.append(sqle.getNextException());
getLogger().error(errorBuffer.toString());
} finally {
theJDBCUtil.closeJDBCResultSet(rsMessageAttr);
theJDBCUtil.closeJDBCStatement(retrieveMessageAttr);
}
}
MailImpl mc = new MailImpl();
mc.setAttributesRaw (attributes);
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);
MimeMessageCopyOnWriteProxy message = new MimeMessageCopyOnWriteProxy(source);
mc.setMessage(message);
return mc;
} catch (SQLException sqle) {
StringBuffer errorBuffer = new StringBuffer(256)
.append("Error retrieving message")
.append(sqle.getMessage())
.append(sqle.getErrorCode())
.append(sqle.getSQLState())
.append(sqle.getNextException());
getLogger().error(errorBuffer.toString());
throw new MessagingException("Exception while retrieving mail: " + sqle.getMessage());
} catch (Exception me) {
throw new MessagingException("Exception while retrieving mail: " + me.getMessage());
} finally {
theJDBCUtil.closeJDBCResultSet(rsMessage);
theJDBCUtil.closeJDBCStatement(retrieveMessage);
theJDBCUtil.closeJDBCConnection(conn);
}
| public void | service(org.apache.avalon.framework.service.ServiceManager componentManager)
StringBuffer logBuffer = null;
if (getLogger().isDebugEnabled()) {
logBuffer =
new StringBuffer(64)
.append(this.getClass().getName())
.append(".compose()");
getLogger().debug(logBuffer.toString());
}
// Get the DataSourceSelector service
datasources = (DataSourceSelector)componentManager.lookup( DataSourceSelector.ROLE );
this.componentManager = componentManager;
| public void | store(org.apache.mailet.Mail mc)Store this message to the database. Optionally stores the message
body to the filesystem and only writes the headers to the database.
Connection conn = null;
boolean wasLocked = true;
String key = mc.getName();
try {
synchronized(this) {
wasLocked = lock.isLocked(key);
if (!wasLocked) {
//If it wasn't locked, we want a lock during the store
lock(key);
}
}
conn = datasource.getConnection();
//Need to determine whether need to insert this record, or update it.
//Begin a transaction
conn.setAutoCommit(false);
PreparedStatement checkMessageExists = null;
ResultSet rsExists = null;
boolean exists = false;
try {
checkMessageExists =
conn.prepareStatement(sqlQueries.getSqlString("checkMessageExistsSQL", true));
checkMessageExists.setString(1, mc.getName());
checkMessageExists.setString(2, repositoryName);
rsExists = checkMessageExists.executeQuery();
exists = rsExists.next() && rsExists.getInt(1) > 0;
} finally {
theJDBCUtil.closeJDBCResultSet(rsExists);
theJDBCUtil.closeJDBCStatement(checkMessageExists);
}
if (exists) {
//Update the existing record
PreparedStatement updateMessage = null;
try {
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();
} finally {
Statement localUpdateMessage = updateMessage;
// Clear reference to statement
updateMessage = null;
theJDBCUtil.closeJDBCStatement(localUpdateMessage);
}
//Determine whether attributes are used and available for storing
if (jdbcMailAttributesReady && mc.hasAttributes()) {
String updateMessageAttrSql =
sqlQueries.getSqlString("updateMessageAttributesSQL", false);
PreparedStatement updateMessageAttr = null;
try {
updateMessageAttr =
conn.prepareStatement(updateMessageAttrSql);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
try {
if (mc instanceof MailImpl) {
oos.writeObject(((MailImpl)mc).getAttributesRaw());
} else {
HashMap temp = new HashMap();
for (Iterator i = mc.getAttributeNames(); i.hasNext(); ) {
String hashKey = (String) i.next();
temp.put(hashKey,mc.getAttribute(hashKey));
}
oos.writeObject(temp);
}
oos.flush();
ByteArrayInputStream attrInputStream =
new ByteArrayInputStream(baos.toByteArray());
updateMessageAttr.setBinaryStream(1, attrInputStream, baos.size());
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException ioe) {
getLogger().debug("JDBCMailRepository: Unexpected exception while closing output stream.",ioe);
}
}
updateMessageAttr.setString(2, mc.getName());
updateMessageAttr.setString(3, repositoryName);
updateMessageAttr.execute();
} catch (SQLException sqle) {
getLogger().info("JDBCMailRepository: Trying to update mail attributes failed.",sqle);
} finally {
theJDBCUtil.closeJDBCStatement(updateMessageAttr);
}
}
//Determine whether the message body has changed, and possibly avoid
// updating the database.
MimeMessage messageBody = mc.getMessage();
boolean saveBody = false;
// if the message is a CopyOnWrite proxy we check the modified wrapped object.
if (messageBody instanceof MimeMessageCopyOnWriteProxy) {
MimeMessageCopyOnWriteProxy messageCow = (MimeMessageCopyOnWriteProxy) messageBody;
messageBody = messageCow.getWrappedMessage();
}
if (messageBody instanceof MimeMessageWrapper) {
MimeMessageWrapper message = (MimeMessageWrapper)messageBody;
saveBody = message.isModified();
} else {
saveBody = true;
}
if (saveBody) {
PreparedStatement updateMessageBody =
conn.prepareStatement(sqlQueries.getSqlString("updateMessageBodySQL", true));
try {
MessageInputStream is = new MessageInputStream(mc,sr,inMemorySizeLimit);
updateMessageBody.setBinaryStream(1,is,(int) is.getSize());
updateMessageBody.setString(2, mc.getName());
updateMessageBody.setString(3, repositoryName);
updateMessageBody.execute();
} finally {
theJDBCUtil.closeJDBCStatement(updateMessageBody);
}
}
} else {
//Insert the record into the database
PreparedStatement insertMessage = null;
try {
String insertMessageSQL = sqlQueries.getSqlString("insertMessageSQL", true);
int number_of_parameters = getNumberOfParameters (insertMessageSQL);
insertMessage =
conn.prepareStatement(insertMessageSQL);
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()));
MessageInputStream is = new MessageInputStream(mc, sr, inMemorySizeLimit);
insertMessage.setBinaryStream(10, is, (int) is.getSize());
//Store attributes
if (number_of_parameters > 10) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
try {
if (mc instanceof MailImpl) {
oos.writeObject(((MailImpl)mc).getAttributesRaw());
} else {
HashMap temp = new HashMap();
for (Iterator i = mc.getAttributeNames(); i.hasNext(); ) {
String hashKey = (String) i.next();
temp.put(hashKey,mc.getAttribute(hashKey));
}
oos.writeObject(temp);
}
oos.flush();
ByteArrayInputStream attrInputStream =
new ByteArrayInputStream(baos.toByteArray());
insertMessage.setBinaryStream(11, attrInputStream, baos.size());
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException ioe) {
getLogger().debug("JDBCMailRepository: Unexpected exception while closing output stream.",ioe);
}
}
}
insertMessage.execute();
} finally {
theJDBCUtil.closeJDBCStatement(insertMessage);
}
}
conn.commit();
conn.setAutoCommit(true);
} catch (Exception e) {
getLogger().error("Exception caught while storing mail Container",e);
throw new MessagingException("Exception caught while storing mail Container: ",e);
} finally {
theJDBCUtil.closeJDBCConnection(conn);
if (!wasLocked) {
// If it wasn't locked, we need to unlock now
unlock(key);
synchronized (this) {
notify();
}
}
}
| public boolean | unlock(java.lang.String key)Releases a lock on a message identified by a key
if (lock.unlock(key)) {
if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
StringBuffer debugBuffer =
new StringBuffer(256)
.append("Unlocked ")
.append(key)
.append(" for ")
.append(Thread.currentThread().getName())
.append(" @ ")
.append(new java.util.Date(System.currentTimeMillis()));
getLogger().debug(debugBuffer.toString());
}
return true;
} else {
return false;
}
|
|