/* * MailMessage.java * * This work is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * This work is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * Copyright (c) 2004-2006 Per Cederberg. All rights reserved. */ package org.liquidsite.util.mail; import java.util.Collection; import java.util.Date; import java.util.HashMap; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import org.liquidsite.util.log.Log; /** * An email message. This is the base class for all types of email * messages in the outgoing mail queue. The queue will iterate over * all the message recipients one by one and send each one a single * unique message. Due to queueing considerations, it is possible * that other messages are delivered before all emails have been * generated for a message. * * @author Per Cederberg, <per at percederberg dot net> * @version 1.0 */ public abstract class MailMessage { /** * The class logger. */ private static final Log LOG = new Log(MailMessage.class); /** * The character set to use for the messages. */ private static final String CHARACTER_SET = "ISO-8859-1"; /** * The message from address. */ private InternetAddress from = null; /** * The message reply-to address. */ private InternetAddress replyTo = null; /** * The message subject. */ private String subject = ""; /** * The message text. */ private String text = ""; /** * The additional message attributes. */ private HashMap attributes = new HashMap(); /** * Checks if this message is valid. A message becomes valid once * it has at least one recipient and non-empty subject and text * content. * * @return true if the message is valid, or * false otherwise */ public boolean isValid() { return subject.length() > 0 && text.length() > 0; } /** * Returns a string representation of the message recipient. This * method is used for logging purposes, so the returned string * shouldn't be too long. * * @return the message recipient */ public abstract String getRecipient(); /** * Returns the message from address. * * @return the message from address, or * null if none has been set */ public String getFrom() { if (from == null) { return null; } else { return from.toString(); } } /** * Returns the message from address. * * @return the message from address, or * null if none has been set */ public InternetAddress getFromAddress() { return from; } /** * Sets the message from address. * * @param address the from address * * @throws MailMessageException if the address wasn't possible to * parse correctly */ public void setFrom(String address) throws MailMessageException { String error; try { if (address == null) { this.from = null; } else { this.from = new InternetAddress(address); } } catch (AddressException e) { error = "failed to parse mail from address '" + address + "'"; LOG.info(error, e); throw new MailMessageException(error, e); } } /** * Returns the message reply to address. * * @return the message reply to address, or * null if none has been set */ public String getReplyTo() { if (replyTo == null) { return null; } else { return replyTo.toString(); } } /** * Returns the message reply to address. * * @return the message reply to address, or * null if none has been set */ public InternetAddress getReplyToAddress() { return replyTo; } /** * Sets the message reply-to address. * * @param address the reply-to address * * @throws MailMessageException if the reply-to address wasn't * possible to parse correctly */ public void setReplyTo(String address) throws MailMessageException { String error; try { if (address == null) { this.replyTo = null; } else { this.replyTo = new InternetAddress(address); } } catch (AddressException e) { error = "failed to parse mail reply-to address '" + address + "'"; LOG.info(error, e); throw new MailMessageException(error, e); } } /** * Returns the message subject. * * @return the message subject, or * an empty string if not set */ public String getSubject() { return subject; } /** * Sets the message subject. * * @param subject the message subject */ public void setSubject(String subject) { this.subject = subject; } /** * Returns the message text. * * @return the message text, or * an empty string if not set */ public String getText() { return text; } /** * Sets the message text. * * @param text the message text */ public void setText(String text) { this.text = text; } /** * Returns the value for a specified attribute. Message attributes * can be used for storing information about the origin of a * message or other information that is not part of the message * itself. * * @param name the message attribute name * * @return the message attribute value, or * null if not set */ public String getAttribute(String name) { return (String) attributes.get(name); } /** * Returns a collection with all the attribute names. Message * attributes can be used for storing information about the origin * of a message or other information that is not part of the * message itself. * * @return a collection with the message attribute names */ public Collection getAttributeNames() { return attributes.keySet(); } /** * Sets a message attribute value. Message attributes can be used * for storing information about the origin of a message or other * information that is not part of the message itself. * * @param name the message attribute name * @param value the message attribute value */ public void setAttribute(String name, String value) { attributes.put(name, value); } /** * Checks if there remains any Java mail MIME messages to * generate. * * @return true if there are more messages to generate, or * false otherwise */ protected abstract boolean hasMoreMessages(); /** * Creates the next Java mail MIME message from this mail * message. * * @param session the Java mail session * * @return the Java MIME message created * * @throws MailMessageException if the message couldn't be * created correctly */ protected abstract MimeMessage getNextMessage(Session session) throws MailMessageException; /** * Creates a Java mail MIME message. * * @param session the Java mail session * @param recipient the mail recipient * * @return the Java MIME message created * * @throws MailMessageException if the message couldn't be * created correctly */ protected MimeMessage createMessage(Session session, InternetAddress recipient) throws MailMessageException { MimeMessage msg = new MimeMessage(session); InternetAddress[] addresses; String error; try { msg.setSentDate(new Date()); if (getFromAddress() == null) { msg.setFrom(); } else { msg.setFrom(getFromAddress()); } if (getReplyToAddress() != null) { addresses = new InternetAddress[1]; addresses[0] = getReplyToAddress(); msg.setReplyTo(addresses); } addresses = new InternetAddress[1]; addresses[0] = recipient; msg.setRecipients(Message.RecipientType.TO, addresses); msg.setSubject(getSubject(), CHARACTER_SET); msg.setText(getText(), CHARACTER_SET); msg.saveChanges(); } catch (MessagingException e) { error = "failed to create mail message to '" + recipient + "'"; LOG.error(error, e); throw new MailMessageException(error, e); } return msg; } }