I don't like making the mailet API tied to the Avalon structure. I'm hoping mailets and matchers can eventually become used enough that other mail server engines start supporting them.
Another idea would to leave the GenericMailet as is, but then also offer a GenericAvalonMailet that would have easier access to Avalon information. I'd probably be +0 on this since it does in effect encourage people to write non-generic mailets. I may just be unrealistic in this hope though. The RemoteDelivery mailet already grabs Avalon resources, which it does by grabbing a ComponentManager from a MailetContext attribute. Seems like this approach could give you similar access to Jdbc sources or whatever. I plan to rewrite the Town alias and Town listserv without Town (using the internal jdbc datasource), and I'll see if I can figure a nice way to get these to work. Serge Knystautas Loki Technologies http://www.lokitech.com/ ----- Original Message ----- From: "Oki DZ" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, September 26, 2001 11:31 PM Subject: Turning mailets into Avalon components > Hi, > > I think it would be nice if James mailets can be changed into Avalon > components. By doing so, you could get access to the might be useful > components from Excalibur or Cornerstone from your mailets. I don't think > there would be many changes in James, all you need is to have > GenericMailet to extend AbstractLoggable and implement Component, and also > some lines in the JamesSpoolManager like in the following: (the "if > (mailet instanceof Component)" might not be needed). > > try { > mailet = mailetLoader.getMailet(mailetClassName, mailetcontext,c); > if (mailet instanceof Component) { > if (mailet instanceof AbstractLoggable) { > ((GenericMailet) mailet).setLogger(getLogger()); > } > if (mailet instanceof Composable) { > ((Composable) mailet).compose(compMgr); > } > if (mailet instanceof Initializable) { > ((Initializable) mailet).initialize(); > } > } > getLogger().info("Mailet " + mailetClassName + " instantiated"); > } catch (MessagingException ex) { > // ... > } > > The init() method in the mailets can be replaced by initialize(), but the > init() signature should be left there (it is invoked by > mailetLoader.getMailet()). But since the code changes in > JamesSpoolRepository tests whether the mailet is a Component or not, the > current mailets (which are not Component) would work as they should be. > > The following is a mailet which stores some information of a message into > a database table; could be useful if you want to have some statistics of > your email users. > > As I understand it, the latest James already uses JdbcDataSource, so the > componentManager.lookup() below can be changed to use the interface (role) > of the block where the latest James gets the JdbcDataSource from. And > also, it would be nicer if the SQL statement used is retrieved from the > SQL repository. > > public class StoreSenderAndRecipients extends GenericMailet > implements Composable, Initializable { > > private String sender; > private String recipients; > private String remoteAddr; > private int size; > > private JdbcDataSource dataSource; > private DataSourceSelector dataSourceSelector; > private String storeSQL; > private JdbcConnection conn; > private PreparedStatement ps; > > public StoreSenderAndRecipients() {} > > public void compose(ComponentManager componentManager) > throws ComponentException { > > dataSourceSelector = (DataSourceSelector) > > componentManager.lookup("com.pindad.james.services.DataSourceSelector"); > getLogger().debug(getClass().getName() + > ".compose(ComponentManager): " + > "Composed"); > } > > public void initialize() throws Exception { > dataSource = (JdbcDataSource) > dataSourceSelector.select("mailetsource"); > storeSQL = > "insert into SenderRecipients (sender, recipients, > remote_addr, size) " + > "values (?, ?, ?, ?)"; > conn = (JdbcConnection) dataSource.getConnection(); > ps = conn.prepareStatement(storeSQL); > getLogger().debug(getClass().getName() + ".initialize(): > Initialized"); > } > > public void init() { > } > > public void service(Mail mail) throws MessagingException { > MimeMessage message = mail.getMessage(); > size = message.getSize(); > MailImpl mc = (MailImpl) mail; > sender = mc.getSender().toString(); > remoteAddr = mc.getRemoteAddr(); > StringBuffer buff = new StringBuffer(); > Collection rcpts = mc.getRecipients(); > for (Iterator i = rcpts.iterator(); i.hasNext();) { > String address = ((MailAddress) i.next()).toString(); > buff.append(address + " "); > } > recipients = buff.toString(); > // System.out.println("Sender: " + sender); > // System.out.println("Recipients: " + recipients); > // System.out.println("Size: " + size); > > try { > ps.setString(1, sender); > ps.setString(2, recipients); > ps.setString(3, remoteAddr); > ps.setInt(4, size); > ps.execute(); > } catch(SQLException sqe) { > getLogger().error(getClass().getName() + ".service(Mail): " + > sqe.getMessage()); > } > } > > public void finalize() { > try { > conn.close(); > } catch(Exception e) { > getLogger().error(getClass().getName() + ".finalize(): " + > e.getMessage()); > } > } > > public String getMailetInfo() { > return getClass().getName(); > } > } > > Just some ideas of improvement (I think), > Oki > ps: Could be nicer if matchers are Components too; say, you'd like to have > your own spam blackhole matcher based on a database table; which could be > neat, because you don't have to restart James to have it in effect. > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
