play.mvc.Mailer Maven / Gradle / Ivy
package play.mvc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.*;
import play.Logger;
import play.classloading.enhancers.LocalvariablesNamesEnhancer.LocalVariablesNamesTracer;
import play.classloading.enhancers.LocalvariablesNamesEnhancer.LocalVariablesSupport;
import play.exceptions.MailException;
import play.exceptions.TemplateNotFoundException;
import play.exceptions.UnexpectedException;
import play.libs.Mail;
import play.templates.Template;
import play.templates.TemplateLoader;
import javax.mail.internet.InternetAddress;
/**
* Application mailer support
*/
public class Mailer implements LocalVariablesSupport {
protected static ThreadLocal> infos = new ThreadLocal>();
/**
* Set subject of mail, optionally providing formatting arguments
* @param subject plain String or formatted string - interpreted as formatted string only if aguments are provided
* @param args optional arguments for formatting subject
*/
public static void setSubject(String subject, Object... args) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
if(args.length != 0){
subject = String.format(subject, args);
}
map.put("subject", subject);
infos.set(map);
}
@SuppressWarnings("unchecked")
public static void addRecipient(Object... recipients) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
List recipientsList = (List) map.get("recipients");
if (recipientsList == null) {
recipientsList = new ArrayList();
map.put("recipients", recipientsList);
}
recipientsList.addAll(Arrays.asList(recipients));
infos.set(map);
}
@SuppressWarnings("unchecked")
public static void addBcc(Object... bccs) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
List bccsList = (List) map.get("bccs");
if (bccsList == null) {
bccsList = new ArrayList();
map.put("bccs", bccsList);
}
bccsList.addAll(Arrays.asList(bccs));
infos.set(map);
}
@SuppressWarnings("unchecked")
public static void addCc(Object... ccs) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
List ccsList = (List) map.get("ccs");
if (ccsList == null) {
ccsList = new ArrayList();
map.put("ccs", ccsList);
}
ccsList.addAll(Arrays.asList(ccs));
infos.set(map);
}
@SuppressWarnings("unchecked")
public static void addAttachment(EmailAttachment... attachments) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
List attachmentsList = (List) map.get("attachments");
if (attachmentsList == null) {
attachmentsList = new ArrayList();
map.put("attachments", attachmentsList);
}
attachmentsList.addAll(Arrays.asList(attachments));
infos.set(map);
}
public static void setContentType(String contentType) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
map.put("contentType", contentType);
infos.set(map);
}
/**
* Can be of the form xxx
*
* @param from
*/
public static void setFrom(Object from) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
map.put("from", from);
infos.set(map);
}
/**
* Can be of the form xxx
*
* @param replyTo
*/
public static void setReplyTo(Object replyTo) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
map.put("replyTo", replyTo);
infos.set(map);
}
public static void setCharset(String bodyCharset) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
map.put("charset", bodyCharset);
infos.set(map);
}
@SuppressWarnings("unchecked")
public static void addHeader(String key, String value) {
HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
HashMap headers = (HashMap) map.get("headers");
if (headers == null) {
headers = new HashMap();
}
headers.put(key, value);
map.put("headers", headers);
infos.set(map);
}
@SuppressWarnings("unchecked")
public static Future send(Object... args) {
try {
final HashMap map = infos.get();
if (map == null) {
throw new UnexpectedException("Mailer not instrumented ?");
}
// Body character set
final String charset = (String) infos.get().get("charset");
// Headers
final Map headers = (Map) infos.get().get("headers");
// Subject
final String subject = (String) infos.get().get("subject");
String templateName = (String) infos.get().get("method");
if (templateName.startsWith("notifiers.")) {
templateName = templateName.substring("notifiers.".length());
}
if (templateName.startsWith("controllers.")) {
templateName = templateName.substring("controllers.".length());
}
templateName = templateName.substring(0, templateName.indexOf("("));
templateName = templateName.replace(".", "/");
// overrides Template name
if (args.length > 0 && args[0] instanceof String && LocalVariablesNamesTracer.getAllLocalVariableNames(args[0]).isEmpty()) {
templateName = args[0].toString();
}
final Map templateHtmlBinding = new HashMap();
final Map templateTextBinding = new HashMap();
for (Object o : args) {
List names = LocalVariablesNamesTracer.getAllLocalVariableNames(o);
for (String name : names) {
templateHtmlBinding.put(name, o);
templateTextBinding.put(name, o);
}
}
// The rule is as follow: If we ask for text/plain, we don't care about the HTML
// If we ask for HTML and there is a text/plain we add it as an alternative.
// If contentType is not specified look at the template available:
// - .txt only -> text/plain
// else
// - -> text/html
String contentType = (String) infos.get().get("contentType");
String bodyHtml = null;
String bodyText = "";
try {
Template templateHtml = TemplateLoader.load(templateName + ".html");
bodyHtml = templateHtml.render(templateHtmlBinding);
} catch (TemplateNotFoundException e) {
if (contentType != null && !contentType.startsWith("text/plain")) {
throw e;
}
}
try {
Template templateText = TemplateLoader.load(templateName + ".txt");
bodyText = templateText.render(templateTextBinding);
} catch (TemplateNotFoundException e) {
if (bodyHtml == null && (contentType == null || contentType.startsWith("text/plain"))) {
throw e;
}
}
// Content type
if (contentType == null) {
if (bodyHtml != null) {
contentType = "text/html";
} else {
contentType = "text/plain";
}
}
// Recipients
final List