/**********************************************************************************
* Copyright 2008 Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.email.api;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.sakaiproject.email.api.EmailAddress.RecipientType;
/**
* Value object for sending emails. Mimics javax.mail.internet.MimeMessage without having a
* dependency on javax.mail<br>
*
* <p>
* Sending a message can be done by specifying recipients and/or <em>actual</em> recipients. If only
* recipients (to, cc, bcc) are specified, those are the people that will recieve the message and
* will see each other listed in the to, cc and bcc fields. If actual recipients are specified, any
* other recipients will be ignored but will be added to the email headers appropriately. This
* allows for mailing to lists and hiding recipients (recipients: mylist@somedomain.edu,
* actualRecipients: [long list of students].
* </p>
*
* <p>
* The default content type for a message is {@link ContentType#TEXT_PLAIN}. The content type only
* applies to the message body.
* </p>
* <p>
* The default character set for a message is UTF-8.
* </p>
*
* @see javax.mail.Transport#send(Message)
* @see javax.mail.Transport#send(Message, Address[])
* @see javax.mail.internet.InternetAddress
*/
public class EmailMessage
{
/**
* Who this message is from
*/
private EmailAddress from;
/**
* Addressee(s) for replies
*/
private List<EmailAddress> replyTo;
/**
* Recipients of message
*/
private Map<RecipientType, List<EmailAddress>> recipients = new HashMap<RecipientType, List<EmailAddress>>();
/**
* Subject of message
*/
private String subject;
/**
* Body content of message
*/
private String body;
/**
* Attachments to consider for message
*/
private List<Attachment> attachments;
/**
* Arbitrary headers for message
*/
private Map<String, String> headers;
/**
* Mime type of message. Defaults to text/plain.
*
* @see org.sakaiproject.email.api.ContentType
*/
private String contentType = ContentType.TEXT_PLAIN;
/**
* Character set of text in message
*
* @see org.sakaiproject.email.api.CharacterSet
*/
private String characterSet = CharacterSet.UTF_8;
/**
* Format of this message if in plain text.
*
* @see org.sakaiproject.email.api.PlainTextFormat
*/
private String format;
/**
* Default constructor.
*/
public EmailMessage()
{
}
public EmailMessage(String from, String subject, String body)
{
setFrom(from);
setSubject(subject);
setBody(body);
}
/**
* Get the sender of this message.
*
* @return The sender of this message.
*/
public EmailAddress getFrom()
{
return from;
}
/**
* Set the sender of this message.
*
* @param email
* Email address of sender.
*/
public void setFrom(String email)
{
this.from = new EmailAddress(email);
}
/**
* Set the sender of this message.
*
* @param emailAddress
* {@link EmailAddress} of message sender.
*/
public void setFrom(EmailAddress emailAddress)
{
this.from = emailAddress;
}
/**
* Get recipient for replies.
*
* @return {@link EmailAddress} of reply to recipient.
*/
public List<EmailAddress> getReplyTo()
{
return replyTo;
}
/**
* Set recipient for replies.
*
* @param emailAddress
* Email string of reply to recipient.
*/
public void addReplyTo(EmailAddress emailAddress)
{
if (replyTo == null)
{
replyTo = new ArrayList<EmailAddress>();
}
replyTo.add(emailAddress);
}
/**
* Set recipient for replies.
*
* @param replyTo
* {@link EmailAddress} of reply to recipient.
*/
public void setReplyTo(List<EmailAddress> replyTo)
{
this.replyTo = replyTo;
}
/**
* Get intended recipients of this message.
*
* @return List of {@link EmailAddress} that will receive this messagel
*/
public Map<RecipientType, List<EmailAddress>> getRecipients()
{
return recipients;
}
/**
* Get recipients of this message that are associated to a certain type
*
* @param type
* @return
* @see javax.mail.Message.RecipientType
*/
public List<EmailAddress> getRecipients(RecipientType type)
{
List<EmailAddress> retval = null;
if (recipients != null)
{
retval = recipients.get(type);
}
return retval;
}
/**
* Add a recipient to this message.
*
* @param type
* How to address the recipient.
* @param email
* Email to send to.
*/
public void addRecipient(RecipientType type, String email)
{
List<EmailAddress> addresses = recipients.get(type);
if (addresses == null)
{
addresses = new ArrayList<EmailAddress>();
}
addresses.add(new EmailAddress(email));
recipients.put(type, addresses);
}
/**
* Add a recipient to this message.
*
* @param type
* How to address the recipient.
* @param name
* Name of recipient.
* @param email
* Email to send to.
*/
public void addRecipient(RecipientType type, String name, String email)
{
List<EmailAddress> addresses = recipients.get(type);
if (addresses == null)
{
addresses = new ArrayList<EmailAddress>();
}
addresses.add(new EmailAddress(email, name));
recipients.put(type, addresses);
}
/**
* Add multiple recipients to this message.
*
* @param type
* How to address the recipients.
* @param addresses
* List of {@link EmailAddress} to add to this message.
*/
public void addRecipients(RecipientType type, List<EmailAddress> addresses)
{
List<EmailAddress> currentAddresses = recipients.get(type);
if (currentAddresses == null)
{
recipients.put(type, addresses);
}
else
{
currentAddresses.addAll(addresses);
}
}
/**
* Set the recipients of this message. This will replace any existing recipients of the same
* type.
*
* @param type
* How to address the recipients.
* @param addresses
* List of {@link EmailAddress} to add to this message.
*/
public void setRecipients(RecipientType type, List<EmailAddress> addresses)
{
if (addresses != null)
{
recipients.put(type, addresses);
}
else
{
recipients.remove(type);
}
}
/**
* Set the recipients of this messsage. This will replace any existing recipients
*
* @param recipients
*/
public void setRecipients(Map<RecipientType, List<EmailAddress>> recipients)
{
this.recipients = recipients;
}
/**
* Get all recipients as a flattened list. This is intended to be used for determining the
* recipients for an SMTP route.
*
* @return list of recipient addresses associated to this message
*/
public List<EmailAddress> getAllRecipients()
{
List<EmailAddress> rcpts = new ArrayList<EmailAddress>();
if (recipients.containsKey(RecipientType.TO))
{
rcpts.addAll(recipients.get(RecipientType.TO));
}
if (recipients.containsKey(RecipientType.CC))
{
rcpts.addAll(recipients.get(RecipientType.CC));
}
if (recipients.containsKey(RecipientType.BCC))
{
rcpts.addAll(recipients.get(RecipientType.BCC));
}
if (recipients.containsKey(RecipientType.ACTUAL))
{
rcpts.addAll(recipients.get(RecipientType.ACTUAL));
}
return rcpts;
}
/**
* Get the subject of this message.
*
* @return The subject of this message. May be empty or null value.
*/
public String getSubject()
{
return subject;
}
/**
* Set the subject of this message.
*
* @param subject
* Subject for this message. Empty and null values allowed.
*/
public void setSubject(String subject)
{
this.subject = subject;
}
/**
* Get the body content of this message.
*
* @return The body content of this message.
*/
public String getBody()
{
return body;
}
/**
* Set the body content of this message.
*
* @param body
* The content of this message.
*/
public void setBody(String body)
{
this.body = body;
}
/**
* Get the attachments on this message
*
* @return List of {@link Attachment} attached to this message.
*/
public List<Attachment> getAttachments()
{
return attachments;
}
/**
* Add an attachment to this message.
*
* @param attachment
* File to attach to this message.
*/
public void addAttachment(Attachment attachment)
{
if (attachment != null)
{
if (attachments == null)
{
attachments = new ArrayList<Attachment>();
}
attachments.add(attachment);
}
}
/**
* Add an attachment to this message. Same as addAttachment(new Attachment(file)).
*
* @param file
*/
public void addAttachment(File file)
{
addAttachment(new Attachment(file, file.getPath()));
}
/**
* Set the attachments of this message. Will replace any existing attachments.
*
* @param attachments
* The attachments to set on this message.
*/
public void setAttachments(List<Attachment> attachments)
{
this.attachments = attachments;
}
/**
* Get the headers of this message.
*
* @return {@link java.util.Map} of headers set on this message.
*/
public Map<String, String> getHeaders()
{
return headers;
}
/**
* Flattens the headers down to "key: value" strings.
*
* @return List of properly formatted headers. List will be 0 length if no headers found. Does
* not return null
*/
public List<String> extractHeaders()
{
List<String> retval = new ArrayList<String>();
if (headers != null)
{
for (String key : headers.keySet())
{
String value = headers.get(key);
if (key != null && value != null)
{
retval.add(key + ": " + value);
}
}
}
return retval;
}
/**
* Remove a header from this message. Does nothing if header is not found.
*
* @param key
*/
public void removeHeader(String key)
{
if (headers != null && !headers.isEmpty() && headers.containsKey(key))
{
headers.remove(key);
}
}
/**
* Add a header to this message. If the key is found in the headers of this message, the value
* is appended to the previous value found and separated by a space. A key of null will not be
* added. If value is null, previous entries of the matching key will be removed.
*
* @param key
* The key of the header.
* @param value
* The value of the header.
*/
public void addHeader(String key, String value)
{
if (headers == null || headers.get(key) == null)
{
setHeader(key, value);
}
else if (key != null && value != null)
{
String prevVal = headers.get(key);
prevVal += " " + value;
headers.put(key, prevVal);
}
else if (value == null)
{
removeHeader(key);
}
}
/**
* Sets a header to this message. Any previous value for this key will be replaced. If value is
* null, previous entries of the matching key will be removed.
*
* @param key
* The key of the header.
* @param value
* The value of the header.
*/
public void setHeader(String key, String value)
{
if (key != null && value != null)
{
if (headers == null)
{
headers = new HashMap<String, String>();
}
headers.put(key, value);
}
}
/**
* Set the headers of this message. Will replace any existing headers.
*
* @param headers
* The headers to use on this message.
*/
public void setHeaders(Map<String, String> headers)
{
this.headers = headers;
}
/**
* Sets headers on this message. The expected format of each header is key: value.
*
* @param headers
*/
public void setHeaders(List<String> headers)
{
if (headers != null)
{
for (String header : headers)
{
int splitPoint = header.indexOf(":");
String key = header.substring(0, splitPoint);
String value = null;
if (splitPoint != header.length() - 1)
{
value = header.substring(splitPoint + 1).trim();
}
setHeader(key, value);
}
}
}
/**
* Get the mime type of this message.
*
* @return {@link org.sakaiproject.email.api.ContentType} of this message.
*/
public String getContentType()
{
return contentType;
}
/**
* Set the mime type of this message.
*
* @param mimeType
* The mime type to use for this message.
* @see org.sakaiproject.email.api.ContentType
*/
public void setContentType(String mimeType)
{
this.contentType = mimeType;
}
/**
* Get the character set for text in this message. Used for the subject and body.
*
* @return The character set used for this message.
*/
public String getCharacterSet()
{
return characterSet;
}
/**
* Set the character set for text in this message.
*
* @param characterSet
* The character set used to render text in this message.
* @see org.sakaiproject.email.api.CharacterSet
*/
public void setCharacterSet(String characterSet)
{
this.characterSet = characterSet;
}
/**
* Gets the format of this message.
*
* @return
*/
public String getFormat()
{
return format;
}
/**
* Set the format of this message if content type is text/plain
*
* @param format
* @see org.sakaiproject.email.api.PlainTextFormat
* @see org.sakaiproject.email.api.ContentType
*/
public void setFormat(String format)
{
this.format = format;
}
}