NIHVIVO-2279 Implement FreemarkerEmailFactory and standardize on it. Change the parameters used to enable e-mail.

This commit is contained in:
j2blake 2011-05-24 19:28:18 +00:00
parent 0bc8cd3c3e
commit 2763d14c6d
10 changed files with 452 additions and 97 deletions

View file

@ -108,8 +108,6 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
message="${deploy.properties.file} must contain a value for vitro.home.directory" /> message="${deploy.properties.file} must contain a value for vitro.home.directory" />
<fail unless="Vitro.defaultNamespace" <fail unless="Vitro.defaultNamespace"
message="${deploy.properties.file} must contain a value for Vitro.defaultNamespace" /> message="${deploy.properties.file} must contain a value for Vitro.defaultNamespace" />
<fail unless="Vitro.smtpHost"
message="${deploy.properties.file} must contain a value for Vitro.smtpHost (may be empty)" />
<fail unless="VitroConnection.DataSource.url" <fail unless="VitroConnection.DataSource.url"
message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.url" /> message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username" <fail unless="VitroConnection.DataSource.username"

View file

@ -7,7 +7,6 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -25,10 +24,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
public class ContactMailServlet extends VitroHttpServlet { public class ContactMailServlet extends VitroHttpServlet {
public static final String SMTPHOST_PROPERTY = "Vitro.smtpHost";
private static final Log log = LogFactory.getLog(ContactMailServlet.class); private static final Log log = LogFactory.getLog(ContactMailServlet.class);
@ -41,24 +39,6 @@ public class ContactMailServlet extends VitroHttpServlet {
private final static String WEB_USEREMAIL_PARAM = "webuseremail"; private final static String WEB_USEREMAIL_PARAM = "webuseremail";
private final static String COMMENTS_PARAM = "s34gfd88p9x1"; private final static String COMMENTS_PARAM = "s34gfd88p9x1";
private static String smtpHost = null;
public static boolean isSmtpHostConfigured(HttpServletRequest req) {
return ConfigurationProperties.getBean(req)
.getProperty(SMTPHOST_PROPERTY, "").length() > 0;
}
@Override
public void init() {
smtpHost = ConfigurationProperties.getBean(getServletContext())
.getProperty(SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
}
@Override @Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) public void doGet( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException { throws ServletException, IOException {
@ -69,9 +49,9 @@ public class ContactMailServlet extends VitroHttpServlet {
String statusMsg = null; // holds the error status String statusMsg = null; // holds the error status
if (smtpHost==null || smtpHost.equals("")){ if (!FreemarkerEmailFactory.isConfigured(vreq)) {
statusMsg = "This application has not yet been configured to send mail " + statusMsg = "This application has not yet been configured to send mail. "
"-- smtp host has not been identified in the Configuration Properties file."; + "Email properties must be specified in the configuration properties file.";
redirectToError(response, statusMsg); redirectToError(response, statusMsg);
return; return;
} }
@ -166,10 +146,7 @@ public class ContactMailServlet extends VitroHttpServlet {
.getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush .getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush
writeBackupCopy(outFile, msgText, spamReason); writeBackupCopy(outFile, msgText, spamReason);
// Set the smtp host Session s = FreemarkerEmailFactory.getEmailSession(vreq);
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true); //s.setDebug(true);
try { try {

View file

@ -6,7 +6,6 @@ import java.io.IOException;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -23,27 +22,14 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao; import edu.cornell.mannlib.vitro.webapp.dao.UserDao;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
public class MailUsersServlet extends VitroHttpServlet { public class MailUsersServlet extends VitroHttpServlet {
private static final Log log = LogFactory.getLog(MailUsersServlet.class); private static final Log log = LogFactory.getLog(MailUsersServlet.class);
public static HttpServletRequest request; public static HttpServletRequest request;
public static HttpServletRequest response; public static HttpServletRequest response;
private static String smtpHost = "";
// private static final Log log = LogFactory.getLog(ContactMailServlet.class.getName());
@Override
public void init() {
smtpHost = ConfigurationProperties.getBean(getServletContext())
.getProperty(ContactMailServlet.SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
}
@Override @Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) public void doGet( HttpServletRequest request, HttpServletResponse response )
@ -54,9 +40,9 @@ public class MailUsersServlet extends VitroHttpServlet {
String errpage = "/contact_err.jsp"; String errpage = "/contact_err.jsp";
String status = null; // holds the error status String status = null; // holds the error status
if (smtpHost==null || smtpHost.equals("")){ if (!FreemarkerEmailFactory.isConfigured(vreq)) {
status = "This application has not yet been configured to send mail " + status = "This application has not yet been configured to send mail. "
"-- smtp host has not been identified in the Configuration Properties file."; + "Email properties must be specified in the configuration properties file.";
response.sendRedirect( "test?bodyJsp=" + errpage + "&ERR=" + status ); response.sendRedirect( "test?bodyJsp=" + errpage + "&ERR=" + status );
return; return;
} }
@ -162,10 +148,8 @@ public class MailUsersServlet extends VitroHttpServlet {
outFile.flush(); outFile.flush();
// outFile.close(); // outFile.close();
*/ */
// Set the smtp host
Properties props = System.getProperties(); Session s = FreemarkerEmailFactory.getEmailSession(vreq);
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true); //s.setDebug(true);
try { try {
// Construct the message // Construct the message

View file

@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
/** /**
* Controller for comments ("contact us") page * Controller for comments ("contact us") page
@ -30,11 +31,12 @@ public class UserMailController extends VitroHttpServlet{
VitroRequest vreq = new VitroRequest(request); VitroRequest vreq = new VitroRequest(request);
try { try {
//this try block passes any errors to error.jsp //this try block passes any errors to error.jsp
if (!ContactMailServlet.isSmtpHostConfigured(request)) { if (!FreemarkerEmailFactory.isConfigured(request)) {
request.setAttribute("title", "Mail All Users Form"); request.setAttribute("title", "Mail All Users Form");
request.setAttribute("bodyJsp", "/contact_err.jsp");// <<< this is where the body gets set request.setAttribute("bodyJsp", "/contact_err.jsp");// <<< this is where the body gets set
request.setAttribute("ERR","This application has not yet been configured to send mail -- " + request.setAttribute("ERR",
"smtp host has not been specified in the configuration properties file."); "This application has not yet been configured to send mail. "
+ "Email properties must be specified in the configuration properties file.");
RequestDispatcher errd = request.getRequestDispatcher(Controllers.BASIC_JSP); RequestDispatcher errd = request.getRequestDispatcher(Controllers.BASIC_JSP);
errd.forward(request, response); errd.forward(request, response);
} }

View file

@ -10,10 +10,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
/** /**
* Controller for comments ("contact us") page * Controller for comments ("contact us") page
@ -40,10 +40,10 @@ public class ContactFormController extends FreemarkerHttpServlet {
String templateName; String templateName;
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
if (!ContactMailServlet.isSmtpHostConfigured(vreq)) { if (!FreemarkerEmailFactory.isConfigured(vreq)) {
body.put("errorMessage", body.put("errorMessage",
"This application has not yet been configured to send mail. " + "This application has not yet been configured to send mail. " +
"An smtp host has not been specified in the configuration properties file."); "Email properties must be specified in the configuration properties file.");
templateName = TEMPLATE_ERROR; templateName = TEMPLATE_ERROR;
} }

View file

@ -10,7 +10,6 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -26,12 +25,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import freemarker.template.Configuration; import freemarker.template.Configuration;
public class ContactMailController extends FreemarkerHttpServlet { public class ContactMailController extends FreemarkerHttpServlet {
@ -51,19 +49,6 @@ public class ContactMailController extends FreemarkerHttpServlet {
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl"; private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
private final static String TEMPLATE_ERROR = "contactForm-error.ftl"; private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
private static String smtpHost = "";
@Override
public void init() {
smtpHost = ConfigurationProperties.getBean(getServletContext())
.getProperty(ContactMailServlet.SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
}
@Override @Override
protected String getTitle(String siteName, VitroRequest vreq) { protected String getTitle(String siteName, VitroRequest vreq) {
return siteName + " Feedback Form"; return siteName + " Feedback Form";
@ -80,10 +65,10 @@ public class ContactMailController extends FreemarkerHttpServlet {
String statusMsg = null; // holds the error status String statusMsg = null; // holds the error status
if (smtpHost.isEmpty()) { if (!FreemarkerEmailFactory.isConfigured(vreq)) {
body.put("errorMessage", body.put("errorMessage",
"This application has not yet been configured to send mail. " + "This application has not yet been configured to send mail. " +
"An smtp host has not been specified in the configuration properties file."); "Email properties must be specified in the configuration properties file.");
templateName = TEMPLATE_ERROR; templateName = TEMPLATE_ERROR;
} }
@ -172,11 +157,7 @@ public class ContactMailController extends FreemarkerHttpServlet {
PrintWriter outFile = new PrintWriter(fw); PrintWriter outFile = new PrintWriter(fw);
writeBackupCopy(outFile, msgText, spamReason, config, vreq); writeBackupCopy(outFile, msgText, spamReason, config, vreq);
// Set the smtp host Session s = FreemarkerEmailFactory.getEmailSession(vreq);
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true);
try { try {
if (spamReason == null) { if (spamReason == null) {

View file

@ -33,6 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Rdf
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
@ -247,7 +248,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
urls.put("base", UrlBuilder.contextPath); urls.put("base", UrlBuilder.contextPath);
urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT)); urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT));
if (ContactMailServlet.isSmtpHostConfigured(vreq)) { if (FreemarkerEmailFactory.isConfigured(vreq)) {
urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT)); urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT));
} }
urls.put("search", urlBuilder.getPortalUrl(Route.SEARCH)); urls.put("search", urlBuilder.getPortalUrl(Route.SEARCH));

View file

@ -0,0 +1,178 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.email;
import java.util.Properties;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* A factory that creates Freemarker-based email messages.
*
* Client code should call isConfigured(), to be sure that the required email
* properties have been provided. If isConfigured() returns false, the client
* code should respond accordingly.
*
* On the other hand, if the configuration properties are provided, but are
* syntactically invalid, an exception is thrown and startup is aborted.
*/
public class FreemarkerEmailFactory {
private static final Log log = LogFactory
.getLog(FreemarkerEmailFactory.class);
public static final String SMTP_HOST_PROPERTY = "email.smtpHost";
public static final String REPLY_TO_PROPERTY = "email.replyTo";
private static final String ATTRIBUTE_NAME = FreemarkerEmailFactory.class
.getName();
// ----------------------------------------------------------------------
// static methods
// ----------------------------------------------------------------------
public static FreemarkerEmailMessage createNewMessage(VitroRequest vreq) {
if (!isConfigured(vreq)) {
throw new IllegalStateException("Email factory is not configured.");
}
FreemarkerEmailFactory factory = getFactory(vreq);
return new FreemarkerEmailMessage(vreq, factory.getEmailSession(),
factory.getReplyToAddress());
}
public static boolean isConfigured(HttpServletRequest req) {
FreemarkerEmailFactory factory = getFactory(req);
return (factory != null) && (factory.isConfigured());
}
/**
* Client code that does not use the FreemarkerEmailFactory can still use
* it's Email Session.
*/
public static Session getEmailSession(HttpServletRequest req) {
if (!isConfigured(req)) {
throw new IllegalStateException("Email factory is not configured.");
}
return getFactory(req).getEmailSession();
}
private static FreemarkerEmailFactory getFactory(HttpServletRequest req) {
ServletContext ctx = req.getSession().getServletContext();
return (FreemarkerEmailFactory) ctx.getAttribute(ATTRIBUTE_NAME);
}
// ----------------------------------------------------------------------
// The factory
// ----------------------------------------------------------------------
private final String smtpHost;
private final InternetAddress replyToAddress;
private final Session emailSession;
public FreemarkerEmailFactory(ServletContext ctx) {
this.smtpHost = getSmtpHostFromConfig(ctx);
this.replyToAddress = getReplyToAddressFromConfig(ctx);
this.emailSession = createEmailSession(this.smtpHost);
}
boolean isConfigured() {
return (!smtpHost.isEmpty()) && (replyToAddress != null);
}
InternetAddress getReplyToAddress() {
return replyToAddress;
}
Session getEmailSession() {
return emailSession;
}
private String getSmtpHostFromConfig(ServletContext ctx) {
ConfigurationProperties config = ConfigurationProperties.getBean(ctx);
String hostName = config.getProperty(SMTP_HOST_PROPERTY, "");
if (hostName.isEmpty()) {
log.info("Configuration property for '" + SMTP_HOST_PROPERTY
+ "' is empty: email is disabled.");
}
return hostName;
}
private InternetAddress getReplyToAddressFromConfig(ServletContext ctx) {
ConfigurationProperties config = ConfigurationProperties.getBean(ctx);
String rawAddress = config.getProperty(REPLY_TO_PROPERTY, "");
if (rawAddress.isEmpty()) {
log.info("Configuration property for '" + REPLY_TO_PROPERTY
+ "' is empty: email is disabled.");
return null;
}
try {
InternetAddress[] addresses = InternetAddress.parse(rawAddress,
false);
if (addresses.length == 0) {
throw new IllegalStateException(
"No Reply-To address configured in '"
+ REPLY_TO_PROPERTY + "'");
} else if (addresses.length > 1) {
throw new IllegalStateException(
"More than one Reply-To address configured in '"
+ REPLY_TO_PROPERTY + "'");
} else {
return addresses[0];
}
} catch (AddressException e) {
throw new IllegalStateException(
"Error while parsing Reply-To address configured in '"
+ REPLY_TO_PROPERTY + "'", e);
}
}
private Session createEmailSession(String hostName) {
Properties props = new Properties(System.getProperties());
props.put("mail.smtp.host", hostName);
return Session.getDefaultInstance(props, null);
}
// ----------------------------------------------------------------------
// Setup class
// ----------------------------------------------------------------------
public static class Setup implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
ctx.setAttribute(ATTRIBUTE_NAME,
new FreemarkerEmailFactory(ctx));
} catch (Exception e) {
log.error(e, e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
}
}
}

View file

@ -0,0 +1,244 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.email;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
import freemarker.template.Configuration;
/**
* A framework that makes it simpler to send email messages with a body built
* from a Freemarker template.
*
* In fact, the body can be plain text from a template, HTML from a template, or
* both.
*/
public class FreemarkerEmailMessage {
private static final Log log = LogFactory
.getLog(FreemarkerEmailMessage.class);
private static final String ATTRIBUTE_NAME = "freemarkerConfig";
private final HttpServletRequest req;
private final Session session;
private final Configuration config;
private final ServletContext ctx;
private final List<Recipient> recipients = new ArrayList<Recipient>();
private final InternetAddress replyToAddress;
private InternetAddress fromAddress = null;
private String subject = "";
private String htmlTemplateName;
private String textTemplateName;
private Map<String, Object> bodyMap = Collections.emptyMap();
/**
* Package access - should only be created by the factory.
*/
FreemarkerEmailMessage(HttpServletRequest req, Session session,
InternetAddress replyToAddress) {
this.req = req;
this.session = session;
this.replyToAddress = replyToAddress;
this.ctx = req.getSession().getServletContext();
Object o = req.getAttribute(ATTRIBUTE_NAME);
if (!(o instanceof Configuration)) {
String oClass = (o == null) ? "null" : o.getClass().getName();
throw new IllegalStateException(
"Request does not contain a Configuration at '"
+ ATTRIBUTE_NAME + "': " + oClass);
}
this.config = (Configuration) o;
}
public void addRecipient(RecipientType type, String emailAddress) {
if (type == null) {
throw new NullPointerException("type may not be null.");
}
if (emailAddress == null) {
log.warn("recipient type was '" + type
+ "', but email address was null.");
return;
}
try {
recipients.add(new Recipient(type, emailAddress));
} catch (AddressException e) {
log.warn("invalid recipient address: " + type + ", '"
+ emailAddress + "'");
return;
}
}
public void addRecipient(RecipientType type, String emailAddress,
String personalName) {
if (personalName == null) {
addRecipient(type, emailAddress);
}
if (type == null) {
throw new NullPointerException("type may not be null.");
}
if (emailAddress == null) {
log.warn("recipient type was '" + type
+ "', but email address was null.");
return;
}
try {
recipients.add(new Recipient(type, emailAddress, personalName));
} catch (AddressException e) {
log.warn("invalid recipient address: " + type + ", '"
+ emailAddress + "', personal name '" + personalName + "'");
return;
} catch (UnsupportedEncodingException e) {
log.warn("invalid recipient address: " + type + ", '"
+ emailAddress + "', personal name '" + personalName + "'");
return;
}
}
public void setSubject(String subject) {
this.subject = nonNull(subject, "");
}
public void setHtmlTemplate(String templateName) {
this.htmlTemplateName = nonNull(templateName, "");
}
public void setTextTemplate(String templateName) {
this.textTemplateName = nonNull(templateName, "");
}
public void setBodyMap(Map<String, Object> body) {
if (body == null) {
this.bodyMap = Collections.emptyMap();
} else {
this.bodyMap = Collections
.unmodifiableMap(new HashMap<String, Object>(body));
}
}
public void send() {
String textBody = figureMessageBody(textTemplateName);
String htmlBody = figureMessageBody(htmlTemplateName);
try {
MimeMessage msg = new MimeMessage(session);
msg.setReplyTo(new Address[] { replyToAddress });
if (fromAddress == null) {
msg.addFrom(new Address[] { replyToAddress });
} else {
msg.addFrom(new Address[] { fromAddress });
}
for (Recipient recipient : recipients) {
msg.addRecipient(recipient.type, recipient.address);
}
msg.setSubject(subject);
if (textBody.isEmpty()) {
if (htmlBody.isEmpty()) {
log.error("Message has neither text body nor HTML body");
} else {
msg.setContent(htmlBody, "text/html");
}
} else {
if (htmlBody.isEmpty()) {
msg.setContent(textBody, "text/plain");
} else {
MimeMultipart content = new MimeMultipart("alternative");
addBodyPart(content, textBody, "text/plain");
addBodyPart(content, htmlBody, "text/html");
msg.setContent(content);
}
}
msg.setSentDate(new Date());
Transport.send(msg);
} catch (MessagingException e) {
log.error("Failed to send message.", e);
}
}
/**
* Process the template. If there is no template name or if there is a
* problem with the process, return an empty string.
*/
private String figureMessageBody(String templateName) {
if (templateName.isEmpty()) {
return "";
}
try {
TemplateProcessingHelper helper = new TemplateProcessingHelper(
config, req, ctx);
return helper.processTemplate(templateName, bodyMap).toString();
} catch (TemplateProcessingException e) {
log.warn("Exception while processing email template '"
+ templateName + "'", e);
return "";
}
}
private void addBodyPart(MimeMultipart content, String textBody, String type)
throws MessagingException {
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(textBody, type);
content.addBodyPart(bodyPart);
}
private <T> T nonNull(T value, T defaultValue) {
return (value == null) ? defaultValue : value;
}
private static class Recipient {
final Message.RecipientType type;
final InternetAddress address;
public Recipient(RecipientType type, String address)
throws AddressException {
this.type = type;
this.address = new InternetAddress(address);
}
public Recipient(RecipientType type, String address, String personalName)
throws AddressException, UnsupportedEncodingException {
this.type = type;
this.address = new InternetAddress(address, personalName);
}
}
}

View file

@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.utils;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.Session; import javax.mail.Session;
@ -16,28 +15,19 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
public class MailUtil { public class MailUtil {
private static final Log log = LogFactory.getLog(MailUtil.class); private static final Log log = LogFactory.getLog(MailUtil.class);
private final HttpServletRequest req;
private String smtpHost = "";
public MailUtil(HttpServletRequest req) { public MailUtil(HttpServletRequest req) {
smtpHost = ConfigurationProperties.getBean(req) this.req = req;
.getProperty(ContactMailServlet.SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
} }
public void sendMessage(String messageText, String subject, String from, String to, List<String> deliverToArray) throws IOException{ public void sendMessage(String messageText, String subject, String from, String to, List<String> deliverToArray) throws IOException{
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost); Session s = FreemarkerEmailFactory.getEmailSession(req);
Session s = Session.getDefaultInstance(props,null);
try{ try{