serge       01/10/31 13:28:45

  Added:       src/java/org/apache/james/transport/mailets
                        JDBCListserv.java
  Log:
  New database driven listserv implementation using straight JDBC.
  
  Revision  Changes    Path
  1.1                  
jakarta-james/src/java/org/apache/james/transport/mailets/JDBCListserv.java
  
  Index: JDBCListserv.java
  ===================================================================
  /*
   * 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.transport.mailets;
  
  import java.io.*;
  import java.sql.*;
  import java.util.*;
  import javax.mail.*;
  import javax.mail.internet.*;
  import org.apache.mailet.*;
  
  import org.apache.avalon.cornerstone.services.datasource.DataSourceSelector;
  import org.apache.avalon.excalibur.datasource.DataSourceComponent;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.james.Constants;
  
  /**
   * Rewrites recipient addresses based on a database table.  The connection
   * is configured by passing the URL to a conn definition.  You need to set
   * the table name to check (or view) along with the source and target columns
   * to use.  For example,
   * <mailet match="All" class="JDBCAlias">
   *   <data_source>maildb</datasource>
   *   <listserv_table>source_email_address</listserv_table>
   *   <members_table>target_email_address</members_table>
   * </mailet>
   *
   * This mailet will cache the settings available when first initialized.  If you wish
   * it to reload for each message, add the init parameter
   * <cache_settings>false</cache_settings>
   *
   * @author  Serge Knystautas <[EMAIL PROTECTED]>
   */
  public class JDBCListserv extends GenericListserv {
  
      protected DataSourceComponent datasource;
      protected String listservID = null;
      protected String listservTable = null;
      protected String membersTable = null;
      protected boolean cacheSettings = true;
  
      //Settings for this listserv
      protected Collection members = null;
      protected boolean membersOnly = true;
      protected boolean attachmentsAllowed = true;
      protected boolean replyToList = true;
      protected MailAddress listservAddress = null;
      protected String subjectPrefix = null;
  
      //Queries to DB
      protected String listservQuery = null;
      protected String membersQuery = null;
  
  
      public void init() throws MessagingException {
          if (getInitParameter("data_source") == null) {
              throw new MailetException("data_source not specified for JDBCListserv");
          }
          if (getInitParameter("listserv_id") == null) {
              throw new MailetException("listserv_id not specified for JDBCListserv");
          }
          if (getInitParameter("listserv_table") == null) {
              throw new MailetException("listserv_table not specified for 
JDBCListserv");
          }
          if (getInitParameter("members_table") == null) {
              throw new MailetException("members_table not specified for 
JDBCListserv");
          }
  
          String datasourceName = getInitParameter("data_source");
          listservID = getInitParameter("listserv_id");
          listservTable = getInitParameter("listserv_table");
          membersTable = getInitParameter("members_table");
  
          if (getInitParameter("cache_settings") != null) {
              try {
                  cacheSettings = new 
Boolean(getInitParameter("cache_settings")).booleanValue();
              } catch (Exception e) {
                  //ignore error
              }
          }
  
          Connection conn = null;
  
          try {
              ComponentManager componentManager = 
(ComponentManager)getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
              // Get the DataSourceSelector block
              DataSourceSelector datasources = 
(DataSourceSelector)componentManager.lookup(DataSourceSelector.ROLE);
              // Get the data-source required.
              datasource = (DataSourceComponent)datasources.select(datasourceName);
  
              conn = datasource.getConnection();
  
              // Check if the required listserv table exists. If not, complain.
              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, listservTable) ||
                      tableExists(dbMetaData, listservTable.toUpperCase()) ||
                      tableExists(dbMetaData, listservTable.toLowerCase()) ))  {
                  throw new MailetException("Could not find table '" + listservTable + 
"' in datasource '" + datasourceName + "'");
              }
  
              // Check if the required members table exists. If not, complain.
              // 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, membersTable) ||
                      tableExists(dbMetaData, membersTable.toUpperCase()) ||
                      tableExists(dbMetaData, membersTable.toLowerCase()) ))  {
                  throw new MailetException("Could not find table '" + membersTable + 
"' in datasource '" + datasourceName + "'");
              }
  
              listservQuery = "SELECT members_only, attachments_allowed, 
reply_to_list, subject_prefix, list_address FROM "
                      + listservTable + " WHERE listserv_id = ?";
              membersQuery = "SELECT member FROM " + membersTable + " WHERE 
listserv_id = ?";
  
              //Always load settings at least once... if we aren't caching, we will 
load at each getMembers() call
              loadSettings();
          } catch (MailetException me) {
              throw me;
          } catch (Exception e) {
              throw new MessagingException("Error initializing JDBCAlias", e);
          } finally {
              try {
                  if (conn != null) {
                      conn.close();
                  }
              } catch (SQLException sqle) {
                  //ignore
              }
          }
      }
  
      /**
       * Returns a Collection of MailAddress objects of members to receive this email
       */
      public Collection getMembers() throws MessagingException {
          if (!cacheSettings) {
              loadSettings();
          }
  
          return members;
      }
  
      /**
       * Returns whether this list should restrict to senders only
       */
      public boolean isMembersOnly() throws MessagingException {
          return membersOnly;
      }
  
      /**
       * Returns whether this listserv allow attachments
       */
      public boolean isAttachmentsAllowed() throws MessagingException {
          return attachmentsAllowed;
      }
  
      /**
       * Returns whether listserv should add reply-to header
       */
      public boolean isReplyToList() throws MessagingException {
          return replyToList;
      }
  
      /**
       * The email address that this listserv processes on.  If returns null, will use 
the
       * recipient of the message, which hopefully will be the correct email address 
assuming
       * the matcher was properly specified.
       */
      public MailAddress getListservAddress() throws MessagingException {
          return listservAddress;
      }
  
      /**
       * An optional subject prefix which will be surrounded by [].
       */
      public String getSubjectPrefix() throws MessagingException {
          return subjectPrefix;
      }
  
      protected void loadSettings() throws MessagingException {
          Connection conn = null;
          PreparedStatement stmt = null;
          ResultSet rs = null;
  
          try {
              //Load members
              conn = getConnection();
              stmt = conn.prepareStatement(membersQuery);
              stmt.setString(1, listservID);
              rs = stmt.executeQuery();
              Collection tmpMembers = new Vector();
              while (rs.next()) {
                  String address = rs.getString(1);
                  try {
                      MailAddress mailAddress = new MailAddress(address);
                      tmpMembers.add(mailAddress);
                  } catch (ParseException pe) {
                      //don't stop... just log and continue
                      log("error parsing address '" + address + "' in listserv '" + 
listservID + "'");
                  }
              }
              rs.close();
              stmt.close();
  
              stmt = conn.prepareStatement(listservQuery);
              stmt.setString(1, listservID);
              rs = stmt.executeQuery();
              if (!rs.next()) {
                  throw new MailetException("Could not find listserv record for '" + 
listservID + "'");
              }
              membersOnly = rs.getBoolean("members_only");
              attachmentsAllowed = rs.getBoolean("attachments_allowed");
              replyToList = rs.getBoolean("reply_to_list");
              subjectPrefix = rs.getString("subject_prefix");
              String address = rs.getString("listserv_address");
              if (address == null) {
                  listservAddress = null;
              } else {
                  try {
                      listservAddress = new MailAddress(address);
                  } catch (ParseException pe) {
                      //log and ignore
                      log("invalid listserv address '" + listservAddress + "' for 
listserv '" + listservID + "'");
                      listservAddress = null;
                  }
              }
              rs.close();
              stmt.close();
          } catch (SQLException sqle) {
              throw new MailetException("Problem loading settings", sqle);
          } finally {
              try {
                  if (conn != null) {
                      conn.close();
                  }
              } catch (SQLException sqle) {
                  //ignore
              }
          }
      }
  
      public String getMailetInfo() {
          return "JDBC listserv mailet";
      }
  
      /**
       * Opens a database connection.
       */
      private Connection getConnection() throws MessagingException {
          try {
              return datasource.getConnection();
          } catch (SQLException sqle) {
              throw new MessagingException (
                  "An exception occurred getting a database connection.", sqle);
          }
      }
  
      /**
       * Checks database metadata to see if a table exists.
       */
      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;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to