package com.waldura.mail; import java.io.InputStream; import java.io.IOException; import java.util.Properties; // JavaMail import javax.mail.*; import javax.mail.internet.*; /** * Facade for JavaMail. Also Singleton. *
* This class declared final because I don't see any
* good reason why anyone would want to extend it. If you need more
* functionality than this class provides, either use JavaMail directly
* or modify the Facade itself to include that functionality.
*
* @author Renaud Waldura, 6/26/2001
*/
public final class Mailer
{
/**
* The name of the default configuration file for this object.
* It is looked up in this classloader's resources using
* {@link Class#getResource(String)}.
*/
public static final String DEFAULT_CONFIG_FILE = "/Mailer.properties";
/**
* Debug JavaMail? Set this property to true to have the
* JavaMail library print debugging statements to System.err.
*/
private static final String DEBUG_JAVAMAIL_PROPERTY = "mail.debug";
// singleton instance
private static Mailer instance = null;
// the JavaMail session
private Session session;
/**
* Private constructor prevents instantiation.
*/
private Mailer() {}
/**
* Configure the mailing sub-system from the given stream.
* It is advised you use
* {@link #configure(String)}
* instead.
*
* @param is a stream the configuration is read from
*
* @throws IOException if failed to read the configuration data from
* file
*/
private void configure(final InputStream is)
throws IOException
{
// load properties from stream
Properties p = new Properties();
p.load(is);
session = Session.getDefaultInstance(p, null);
// debugging?
String debug = p.getProperty( DEBUG_JAVAMAIL_PROPERTY );
session.setDebug( "true".equals(debug) );
}
/**
* Configure the mailing sub-system from the given file.
* The file is looked up in the same directory as the compiled class
* file, using
* {@link Class#getResourceAsStream}.
*
* @param configFile the name of the configuration file
*
* @throws IOException if failed to read the configuration data from
* file
*/
public void configure(final String configFile)
throws IOException
{
configure( getClass().getResourceAsStream(configFile) );
}
/**
* Configure the mailing sub-system.
* The {@link #DEFAULT_CONFIG_FILE DEFAULT_CONFIG_FILE} is used
* for the configuration data.
*
* @throws MailingException if the sub-system configuration failed
*/
public void configure()
throws MailingException
{
try
{
configure(DEFAULT_CONFIG_FILE);
}
catch (IOException ioe)
{
// re-type and propagate
throw new MailingException("Configuration failed", ioe);
}
}
/**
* Implementation of the Singleton pattern.
*
* @throws MailingException if initializing the sub-system failed
*/
public static synchronized Mailer getInstance()
throws MailingException
{
if (instance == null)
{
instance = new Mailer();
instance.configure();
}
return instance;
}
/**
* Parse a list of addresses into an array of
* Address objects.
*
* @returns an array of Address objects
*
* @throws AddressException if failed
*/
private Address[] parseAddresses(final String addressList)
throws AddressException
{
return InternetAddress.parse(addressList, true); // strict parsing?
}
/**
* Sends an e-mail message.
*
* @param mail the e-mail message to send
*
* @throws IllegalArgumentException if the message to send is invalid
* in some way
*
* @throws MailingException if anything else went wrong
*/
public void send(final MailMessage mail)
throws MailingException
{
Address from = null;
Address[] to = null;
Address[] cc = null;
String subject, body;
try // pre-conditions
{
String addr = null;
// From is required
addr = mail.getFrom();
if (addr == null) throw new IllegalArgumentException("Email \"from\" address is undefined");
from = parseAddresses(addr)[0];
// To is required
addr = mail.getTo();
if (addr == null) throw new IllegalArgumentException("Email \"to\" address is undefined");
to = parseAddresses(addr);
// Cc is optional
addr = mail.getCc();
if (addr != null) cc = parseAddresses(addr);
// Subject is required
subject = mail.getSubject();
if (subject == null) throw new IllegalArgumentException("No e-mail subject");
// Body is required
body = mail.getBody();
if (body == null) throw new IllegalArgumentException("No e-mail body");
}
catch (AddressException ae)
{
throw new MailingException("One or more addresses of the message are invalid", ae);
}
try
{
// prepare message to be sent
Message m = new MimeMessage(session);
// set "From" address
m.setFrom( from );
// set "To" addresses
m.setRecipients(Message.RecipientType.TO, to);
// set "Cc" addresses
if (cc != null)
m.setRecipients(Message.RecipientType.CC, cc);
// set subject
m.setSubject(subject);
// set body
m.setText(body);
// send it now
Transport.send(m);
}
catch (MessagingException me)
{
throw new MailingException("Unable to send the message", me);
}
}
}