james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject cvs commit: jakarta-james/src/java/org/apache/james/mailrepository AvalonMailRepository.java JDBCMailRepository.java JDBCSpoolRepository.java MimeMessageJDBCSource.java
Date Tue, 11 Sep 2001 04:33:08 GMT
serge       01/09/10 21:33:08

  Modified:    src/java/org/apache/james/mailrepository
                        AvalonMailRepository.java JDBCMailRepository.java
                        JDBCSpoolRepository.java MimeMessageJDBCSource.java
  Log:
  Adding code from userstore branch.
  
  Revision  Changes    Path
  1.7       +26 -12    jakarta-james/src/java/org/apache/james/mailrepository/AvalonMailRepository.java
  
  Index: AvalonMailRepository.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/mailrepository/AvalonMailRepository.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AvalonMailRepository.java	2001/08/06 04:17:03	1.6
  +++ AvalonMailRepository.java	2001/09/11 04:33:08	1.7
  @@ -7,6 +7,9 @@
    */
   package org.apache.james.mailrepository;
   
  +import java.io.EOFException;
  +import java.io.FileNotFoundException;
  +import java.io.IOException;
   import java.io.InputStream;
   import java.io.OutputStream;
   import java.util.Iterator;
  @@ -92,7 +95,7 @@
               sr = (StreamRepository) store.select(streamConfiguration);
               or = (ObjectRepository) store.select(objectConfiguration);
               lock = new Lock();
  -	        getLogger().debug(this.getClass().getName() + " created in " + destination);
  +            getLogger().debug(this.getClass().getName() + " created in " + destination);
           } catch (Exception e) {
               final String message = "Failed to retrieve Store component:" + e.getMessage();
               getLogger().error( message, e );
  @@ -125,30 +128,41 @@
               mc.writeMessageTo(out);
               out.close();
               or.put(key, mc);
  -	    if(DEEP_DEBUG) getLogger().debug("Mail " + key + " stored." );
  +        if(DEEP_DEBUG) getLogger().debug("Mail " + key + " stored." );
               notifyAll();
           } catch (Exception e) {
  -	    getLogger().error("Exception storing mail: " + e);
  +        getLogger().error("Exception storing mail: " + e);
               e.printStackTrace();
               throw new RuntimeException("Exception caught while storing Message Container:
" + e);
           }
       }
   
       public MailImpl retrieve(String key) {
  -	if(DEEP_DEBUG) getLogger().debug("Retrieving mail: " + key);
  -        MailImpl mc = (MailImpl) or.get(key);
  +        if(DEEP_DEBUG) {
  +            getLogger().debug("Retrieving mail: " + key);
  +        }
           try {
  -			MimeMessageAvalonSource source = new MimeMessageAvalonSource(sr, key);
  -			mc.setMessage(new MimeMessageWrapper(source));
  +            MailImpl mc = (MailImpl) or.get(key);
  +            MimeMessageAvalonSource source = new MimeMessageAvalonSource(sr, key);
  +            mc.setMessage(new MimeMessageWrapper(source));
   
  -            //InputStream in = new FileMimeMessageInputStream(sr, key);
  -            //mc.setMessage(in);
  -            //in.close();
  +            return mc;
           } catch (Exception me) {
  -	    getLogger().error("Exception retrieving mail: " + me);
  +            if (me instanceof IOException) {
  +				getLogger().error("IOException retrieving mail: " + me + ", so we're deleting it...
good ridance!");
  +				remove(key);
  +				return null;
  +			}
  +			/*
  +            if (me instanceof FileNotFoundException ||
  +            	me instanceof EOFException) {
  +                remove(key);
  +                return null;
  +            }
  +            */
  +            getLogger().error("Exception retrieving mail: " + me);
               throw new RuntimeException("Exception while retrieving mail: " + me.getMessage());
           }
  -        return mc;
       }
   
       public void remove(MailImpl mail) {
  
  
  
  1.5       +172 -66   jakarta-james/src/java/org/apache/james/mailrepository/JDBCMailRepository.java
  
  Index: JDBCMailRepository.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/mailrepository/JDBCMailRepository.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- JDBCMailRepository.java	2001/08/11 21:25:43	1.4
  +++ JDBCMailRepository.java	2001/09/11 04:33:08	1.5
  @@ -8,6 +8,7 @@
   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;
  @@ -21,19 +22,24 @@
   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.Properties;
  +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;
  @@ -44,91 +50,109 @@
   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;
   
   /**
    * 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>/<repository_name>"
  + *  <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 <sergek@lokitech.com>
  + * @author Darrell DeBoer <dd@bigdaz.com>
    * @version 1.0.0, 24/04/1999
  - * @author  Serge Knystautas <sergek@lokitech.com>
    */
   public class JDBCMailRepository
       extends AbstractLoggable
  -    implements MailRepository, Component, Configurable, Composable {
  +    implements MailRepository, Component, Configurable, Composable, Initializable 
  +{
   
       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 table where this is stored
  -    private String driverClassName;
  -    protected String jdbcURL;
  -    protected String jdbcUsername;   //optional
  -    protected String jdbcPassword;    //optional
  +    //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 configure(Configuration conf) throws ConfigurationException 
  +    {
  +        getLogger().debug(this.getClass().getName() + ".configure()");
   
  -    protected Properties sqlQueries = null;
   
  -    public void configure(Configuration conf) throws ConfigurationException {
           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;
  +        int end = destination.indexOf('/', start);
  +        while ( end > -1 ) {
  +            urlParams.add(destination.substring(start, end));
  +            start = end + 1;
  +            end = destination.indexOf('/', start);
  +        }
   
  -    public void compose( final ComponentManager componentManager )
  -        throws ComponentException {
  -        try {
  -            Properties props = new Properties();
  -            InputStream in = new FileInputStream(destination.substring(5));
  -            props.load(in);
  -            in.close();
  -
  -            driverClassName = props.getProperty("driver");
  -            jdbcURL = props.getProperty("URL");
  -            jdbcUsername = props.getProperty("username");   //optional
  -            jdbcPassword = props.getProperty("password");    //optional
  -
  -            Class.forName(driverClassName);
  -
  -            tableName = props.getProperty("table");
  -            repositoryName = props.getProperty("repository");
  -
  -            //Loop through and replace <table> with the actual table name in each
case
  -            sqlQueries = new Properties();
  -            for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
  -                String key = (String)e.nextElement();
  -                if (!(key.endsWith("SQL"))) {
  -                    continue;
  -                }
  -                String query = props.getProperty(key);
  -                int i = query.indexOf("<table>");
  -                if (i > -1) {
  -                    query = query.substring(0, i) + tableName + query.substring(i + 7);
  -                }
  -                //System.err.println(query);
  -                sqlQueries.put(key, query);
  -            }
  +        // Build SqlParameters and get datasource name from URL parameters
  +        switch ( urlParams.size() ) {
  +        case 3:
  +            repositoryName = (String)urlParams.get(2);
  +        case 2:
  +            tableName = (String)urlParams.get(1);
  +        case 1:
  +            datasourceName = (String)urlParams.get(0);
  +            break;
  +        default:
  +            throw new ConfigurationException
  +                ("Malformed destinationURL - Must be of the format \"" +
  +                 "db://<data-source>[/<table>[/<repositoryName>]]\".");
  +        }
   
  +        getLogger().debug("Parsed URL: table = '" + tableName + 
  +                          "', repositoryName = '" + repositoryName + "'");
  +        
  +        filestore = conf.getChild("filestore").getValue(null);
  +        sqlFileName = conf.getChild("sqlFile").getValue();
  +    }
   
  -            String filestore = props.getProperty("filestore");
  +    public void compose( final ComponentManager componentManager )
  +        throws ComponentException 
  +    {
  +        getLogger().debug(this.getClass().getName() + ".compose()");
   
  -            if (filestore != null) {
  +        // 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",
  @@ -138,6 +162,8 @@
                   streamConfiguration.setAttribute( "type", "STREAM" );
                   streamConfiguration.setAttribute( "model", "SYNCHRONOUS" );
                   sr = (StreamRepository) store.select(streamConfiguration);
  +
  +                getLogger().debug("Got filestore for JdbcMailRepository: " + filestore);
               }
   
               lock = new Lock();
  @@ -150,6 +176,82 @@
           }
       }
   
  +    /**
  +     * 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()");
  +        
  +        // Get the data-source required.
  +        datasource = (DataSourceComponent)datasources.select(datasourceName);
  +
  +        // Test the connection to the database, by getting the DatabaseMetaData.
  +        Connection conn = getConnection();
  +        
  +        try{
  +            // Initialise the sql strings.
  +            java.io.File sqlFile = new java.io.File(sqlFileName);
  +
  +            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 {
  +            conn.close();
  +        }
  +    }
  +
  +
  +    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();
  @@ -178,7 +280,8 @@
               //Begin a transaction
               conn.setAutoCommit(false);
   
  -            PreparedStatement checkMessageExists = conn.prepareStatement(sqlQueries.getProperty("checkMessageExistsSQL"));
  +            PreparedStatement checkMessageExists = 
  +                conn.prepareStatement(sqlQueries.getSqlString("checkMessageExistsSQL",
true));
               checkMessageExists.setString(1, mc.getName());
               checkMessageExists.setString(2, repositoryName);
               ResultSet rsExists = checkMessageExists.executeQuery();
  @@ -188,7 +291,8 @@
   
               if (exists) {
                   //Update the existing record
  -                PreparedStatement updateMessage = conn.prepareStatement(sqlQueries.getProperty("updateMessageSQL"));
  +                PreparedStatement updateMessage = 
  +                    conn.prepareStatement(sqlQueries.getSqlString("updateMessageSQL", true));
                   updateMessage.setString(1, mc.getState());
                   updateMessage.setString(2, mc.getErrorMessage());
                   if (mc.getSender() == null) {
  @@ -224,7 +328,8 @@
                   }
   
                   if (saveBody) {
  -                    updateMessage = conn.prepareStatement(sqlQueries.getProperty("updateMessageBodySQL"));
  +                    updateMessage = 
  +                        conn.prepareStatement(sqlQueries.getSqlString("updateMessageBodySQL",
true));
                       ByteArrayOutputStream headerOut = new ByteArrayOutputStream();
                       OutputStream bodyOut = null;
                       if (sr == null) {
  @@ -249,7 +354,8 @@
                   }
               } else {
                   //Insert the record into the database
  -                PreparedStatement insertMessage = conn.prepareStatement(sqlQueries.getProperty("insertMessageSQL"));
  +                PreparedStatement insertMessage = 
  +                    conn.prepareStatement(sqlQueries.getSqlString("insertMessageSQL", true));
                   insertMessage.setString(1, mc.getName());
                   insertMessage.setString(2, repositoryName);
                   insertMessage.setString(3, mc.getState());
  @@ -311,7 +417,8 @@
           try {
               Connection conn = getConnection();
   
  -            PreparedStatement retrieveMessage = conn.prepareStatement(sqlQueries.getProperty("retrieveMessageSQL"));
  +            PreparedStatement retrieveMessage = 
  +                conn.prepareStatement(sqlQueries.getSqlString("retrieveMessageSQL", true));
               retrieveMessage.setString(1, key);
               retrieveMessage.setString(2, repositoryName);
               ResultSet rsMessage = retrieveMessage.executeQuery();
  @@ -368,7 +475,8 @@
           if (lock(key)) {
               try {
                   Connection conn = getConnection();
  -                PreparedStatement removeMessage = conn.prepareStatement(sqlQueries.getProperty("removeMessageSQL"));
  +                PreparedStatement removeMessage = 
  +                    conn.prepareStatement(sqlQueries.getSqlString("removeMessageSQL", true));
                   removeMessage.setString(1, key);
                   removeMessage.setString(2, repositoryName);
                   removeMessage.execute();
  @@ -390,7 +498,8 @@
           //System.err.println("listing messages");
           try {
               Connection conn = getConnection();
  -            PreparedStatement listMessages = conn.prepareStatement(sqlQueries.getProperty("listMessagesSQL"));
  +            PreparedStatement listMessages = 
  +                conn.prepareStatement(sqlQueries.getSqlString("listMessagesSQL", true));
               listMessages.setString(1, repositoryName);
               ResultSet rsListMessages = listMessages.executeQuery();
   
  @@ -413,14 +522,11 @@
        */
       protected Connection getConnection() {
           try {
  -            if (jdbcUsername == null ) {
  -                return DriverManager.getConnection(jdbcURL);
  -            } else {
  -                return DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);
  -            }
  -        } catch (SQLException sqlExc) {
  -            sqlExc.printStackTrace();
  -            throw new RuntimeException("Error connecting to database");
  +            return datasource.getConnection();
  +        }
  +        catch (SQLException sqle) {
  +            throw new CascadingRuntimeException(
  +                "An exception occurred getting a database connection.", sqle);
           }
       }
   
  
  
  
  1.4       +4 -2      jakarta-james/src/java/org/apache/james/mailrepository/JDBCSpoolRepository.java
  
  Index: JDBCSpoolRepository.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/mailrepository/JDBCSpoolRepository.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JDBCSpoolRepository.java	2001/08/06 04:17:03	1.3
  +++ JDBCSpoolRepository.java	2001/09/11 04:33:08	1.4
  @@ -66,7 +66,8 @@
               try {
                   //System.err.println("querying db");
                   Connection conn = getConnection();
  -                PreparedStatement listMessages = conn.prepareStatement(sqlQueries.getProperty("listMessagesSQL"));
  +                PreparedStatement listMessages = 
  +                    conn.prepareStatement(sqlQueries.getSqlString("listMessagesSQL", true));
                   listMessages.setString(1, repositoryName);
                   ResultSet rsListMessages = listMessages.executeQuery();
   
  @@ -99,7 +100,8 @@
               long next = 0;
               try {
                   Connection conn = getConnection();
  -                PreparedStatement listMessages = conn.prepareStatement(sqlQueries.getProperty("listMessagesSQL"));
  +                PreparedStatement listMessages = 
  +                    conn.prepareStatement(sqlQueries.getSqlString("listMessagesSQL", true));
                   listMessages.setString(1, repositoryName);
                   ResultSet rsListMessages = listMessages.executeQuery();
   
  
  
  
  1.2       +6 -2      jakarta-james/src/java/org/apache/james/mailrepository/MimeMessageJDBCSource.java
  
  Index: MimeMessageJDBCSource.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/mailrepository/MimeMessageJDBCSource.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MimeMessageJDBCSource.java	2001/08/06 03:42:18	1.1
  +++ MimeMessageJDBCSource.java	2001/09/11 04:33:08	1.2
  @@ -19,6 +19,7 @@
   import java.sql.Statement;
   import org.apache.james.core.MimeMessageSource;
   import org.apache.avalon.cornerstone.services.store.StreamRepository;
  +import org.apache.james.util.SqlResources;
   
   /**
    * This class points to a specific message in a repository.  This will return an
  @@ -50,8 +51,11 @@
           this.key = key;
           this.sr = sr;
   
  -        retrieveMessageBodySQL = repository.sqlQueries.getProperty("retrieveMessageBodySQL");
  -        retrieveMessageBodySizeSQL = repository.sqlQueries.getProperty("retrieveMessageBodySizeSQL");
  +        retrieveMessageBodySQL = 
  +            repository.sqlQueries.getSqlString("retrieveMessageBodySQL", true);
  +        // this is optional
  +        retrieveMessageBodySizeSQL = 
  +            repository.sqlQueries.getSqlString("retrieveMessageBodySizeSQL");
       }
   
       /**
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Mime
View raw message