FileDocCategorySizeDatePackage
MimeMessageJDBCSource.javaAPI DocApache James 2.3.110195Fri Jan 12 12:56:24 GMT 2007org.apache.james.mailrepository

MimeMessageJDBCSource

public class MimeMessageJDBCSource extends org.apache.james.core.MimeMessageSource
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.

Fields Summary
private static final boolean
DEEP_DEBUG
Whether 'deep debugging' is turned on.
JDBCMailRepository
repository
String
key
org.apache.avalon.cornerstone.services.store.StreamRepository
sr
private long
size
String
retrieveMessageBodySQL
SQL used to retrieve the message body
String
retrieveMessageBodySizeSQL
SQL used to retrieve the size of the message body
private static final org.apache.james.util.JDBCUtil
theJDBCUtil
The JDBCUtil helper class
Constructors Summary
public MimeMessageJDBCSource(JDBCMailRepository repository, String key, org.apache.avalon.cornerstone.services.store.StreamRepository sr)
Construct a MimeMessageSource based on a JDBC repository, a key, and a stream repository (where we might store the message body)


                              
      
                  
        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;

        retrieveMessageBodySQL =
            repository.sqlQueries.getSqlString("retrieveMessageBodySQL", true);
        // this is optional
        retrieveMessageBodySizeSQL =
            repository.sqlQueries.getSqlString("retrieveMessageBodySizeSQL");
    
Methods Summary
public booleanequals(java.lang.Object obj)
Check to see whether this is the same repository and the same key

        if (obj instanceof MimeMessageJDBCSource) {
            // TODO: Figure out whether other instance variables should be part of
            // the equals equation
            MimeMessageJDBCSource source = (MimeMessageJDBCSource)obj;
            return ((source.key == key) || ((source.key != null) && source.key.equals(key))) &&
                   ((source.repository == repository) || ((source.repository != null) && source.repository.equals(repository)));
        }
        return false;
    
public synchronized java.io.InputStreamgetInputStream()
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.

        Connection conn = null;
        PreparedStatement retrieveMessageStream = null;
        ResultSet rsRetrieveMessageStream = null;
        try {
            conn = repository.getConnection();

            byte[] headers = null;

            long start = 0;
            if (DEEP_DEBUG) {
                start = System.currentTimeMillis();
                System.out.println("starting");
            }
            retrieveMessageStream = conn.prepareStatement(retrieveMessageBodySQL);
            retrieveMessageStream.setString(1, key);
            retrieveMessageStream.setString(2, repository.repositoryName);
            rsRetrieveMessageStream = retrieveMessageStream.executeQuery();

            if (!rsRetrieveMessageStream.next()) {
                throw new IOException("Could not find message");
            }

            String getBodyOption = repository.sqlQueries.getDbOption("getBody");
            if (getBodyOption != null && getBodyOption.equalsIgnoreCase("useBlob")) {
                Blob b = rsRetrieveMessageStream.getBlob(1);
                headers = b.getBytes(1, (int)b.length());
            } else {
                headers = rsRetrieveMessageStream.getBytes(1);
            }
            if (DEEP_DEBUG) {
                System.err.println("stopping");
                System.err.println(System.currentTimeMillis() - start);
            }

            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());
        } finally {
            theJDBCUtil.closeJDBCResultSet(rsRetrieveMessageStream);
            theJDBCUtil.closeJDBCStatement(retrieveMessageStream);
            theJDBCUtil.closeJDBCConnection(conn);
        }
    
public synchronized longgetMessageSize()
Runs a custom SQL statement to check the size of the message body

        if (size != -1) return size;
        if (retrieveMessageBodySizeSQL == null) {
            //There was no SQL statement for this repository... figure it out the hard way
            System.err.println("no SQL statement to find size");
            return size = super.getMessageSize();
        }
        Connection conn = null;
        PreparedStatement retrieveMessageSize = null;
        ResultSet rsRetrieveMessageSize = null;
        try {
            conn = repository.getConnection();

            retrieveMessageSize = conn.prepareStatement(retrieveMessageBodySizeSQL);
            retrieveMessageSize.setString(1, key);
            retrieveMessageSize.setString(2, repository.repositoryName);
            rsRetrieveMessageSize = retrieveMessageSize.executeQuery();

            if (!rsRetrieveMessageSize.next()) {
                throw new IOException("Could not find message");
            }

            size = rsRetrieveMessageSize.getLong(1);

            InputStream in = null;
            try {
                if (sr != null) {
                    if (sr instanceof org.apache.james.mailrepository.filepair.File_Persistent_Stream_Repository) {
                        size += ((org.apache.james.mailrepository.filepair.File_Persistent_Stream_Repository) sr).getSize(key);
                    } else {
                        in = sr.get(key);
                        int len = 0;
                        byte[] block = new byte[1024];
                        while ((len = in.read(block)) > -1) {
                            size += len;
                        }
                    }
                }
            } catch (Exception e) {
                //ignore this... either sr is null, or the file does not exist
                // or something else
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException ioe) {
                    // Ignored - no access to logger at this point in the code
                }
            }
            
            return size;
        } catch (SQLException sqle) {
            throw new IOException(sqle.toString());
        } finally {
            theJDBCUtil.closeJDBCResultSet(rsRetrieveMessageSize);
            theJDBCUtil.closeJDBCStatement(retrieveMessageSize);
            theJDBCUtil.closeJDBCConnection(conn);
        }
    
public java.lang.StringgetSourceId()
Returns a unique String ID that represents the location from where this source is loaded. This will be used to identify where the data is, primarily to avoid situations where this data would get overwritten.

return
the String ID

        StringBuffer sourceIdBuffer =
            new StringBuffer(128)
                    .append(repository.repositoryName)
                    .append("/")
                    .append(key);
        return sourceIdBuffer.toString();
    
public inthashCode()
Provide a hash code that is consistent with equals for this class

return
the hash code

        int result = 17;
        if (key != null) {
            result = 37 * key.hashCode();
        }
        if (repository != null) {
            result = 37 * repository.hashCode();
        }
        return result;