From 2f1b0409529713bdfd3915b1cf57c2b512e3b76f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Tue, 17 May 2016 15:46:32 +0200 Subject: [PATCH] Refacuring: - the wrapper class now takes a Locale, Address (recipient), subject line and template name - rewrote mailer to use Apache Velocity template engine - added a lot cool headers for better UTF-8 support in mails --- .../jmailee/model/delivery/BaseMailer.java | 123 ++++++++++++++++-- .../model/delivery/DeliverableEmail.java | 8 ++ .../wrapper/EmailDeliveryWrapper.java | 97 ++++++-------- .../wrapper/WrapableEmailDelivery.java | 44 +++++-- 4 files changed, 189 insertions(+), 83 deletions(-) diff --git a/src/org/mxchange/jmailee/model/delivery/BaseMailer.java b/src/org/mxchange/jmailee/model/delivery/BaseMailer.java index d7645dc..d7e4db9 100644 --- a/src/org/mxchange/jmailee/model/delivery/BaseMailer.java +++ b/src/org/mxchange/jmailee/model/delivery/BaseMailer.java @@ -16,8 +16,11 @@ */ package org.mxchange.jmailee.model.delivery; +import java.io.StringWriter; import java.text.MessageFormat; import java.util.Date; +import java.util.Properties; +import javax.mail.Address; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; @@ -26,8 +29,12 @@ import javax.mail.internet.MimeMessage; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; import org.mxchange.jcoreeelogger.beans.local.logger.Log; import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal; +import org.mxchange.jmailee.model.delivery.wrapper.WrapableEmailDelivery; /** * An email class for sending out mails from templates @@ -47,6 +54,21 @@ public abstract class BaseMailer implements DeliverableEmail { @Log private LoggerBeanLocal loggerBeanLocal; + /** + * Properties for this mailer + *

+ * Valid are: - mailer.errorsto = Email address for "Errors-To" header - + * mailer.bouncesto = Email address for "Bounces-To" header (optional, if + * not set, errorsto must be set) - mailer.xloop = Email address for + * "X-Loop" header (optional, if not set, errorsto must be set) + */ + private Properties properties; + + /** + * Template engine + */ + private final VelocityEngine templateEngine; + /** * Default constructor */ @@ -61,15 +83,15 @@ public abstract class BaseMailer implements DeliverableEmail { // Continue to throw throw new RuntimeException(MessageFormat.format("context.lookup() failed: {0}", ex.getMessage()), ex); //NOI18N } + + // Init template engine + this.templateEngine = new VelocityEngine(); + this.templateEngine.init(); } - /** - * Getter for logger bean - *

- * @return Local logger bean - */ - protected LoggerBeanLocal getLoggerBeanLocal () { - return this.loggerBeanLocal; + @Override + public VelocityEngine getTemplateEngine () { + return this.templateEngine; } /** @@ -80,21 +102,102 @@ public abstract class BaseMailer implements DeliverableEmail { * @param body Body part * @param mailSession Corresponding mail session to use *

- * @throws NamingException If the resource cannot be found * @throws MessagingException If something happened on message delivery */ - protected void sendMail (final String emailAddress, final String subjectLine, final String body, final Session mailSession) throws NamingException, MessagingException { + private void sendMail (final Address emailAddress, final String subjectLine, final String body, final Session mailSession) throws MessagingException { // Get MIME message instance MimeMessage message = new MimeMessage(mailSession); // Set subject, recipients and body message.setSubject(subjectLine); - message.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(emailAddress, true)); + message.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(emailAddress.toString(), true)); message.setSentDate(new Date()); message.setText(body); + message.setHeader("MIME-Version", "1.0"); //NOI18N + message.setHeader("Content-Type", "text/plain; charset=UTF-8"); //NOI18N + message.setHeader("Content-Transfer-Encoding", "8bit"); //NOI18N + message.setHeader("Errors-To", this.properties.getProperty("mailer.errorsto")); //NOI18N + + // Is the property "bouncesto" set? + if (this.properties.containsKey("mailer.bouncesto")) { //NOI18N + // Use this + message.setHeader("Bounces-To", this.properties.getProperty("mailer.bouncesto")); //NOI18N + } else { + // Use "errorsto" + message.setHeader("Bounces-To", this.properties.getProperty("mailer.errorsto")); //NOI18N + } + + // Is the property "xloop" set? + if (this.properties.containsKey("mailer.xloop")) { //NOI18N + // Use this + message.setHeader("X-Loop", this.properties.getProperty("mailer.xloop")); //NOI18N + } else { + // Use "errorsto" + message.setHeader("X-Loop", this.properties.getProperty("mailer.errorsto")); //NOI18N + } // Directly send email Transport.send(message); } + /** + * Getter for logger bean + *

+ * @return Local logger bean + */ + protected LoggerBeanLocal getLoggerBeanLocal () { + return this.loggerBeanLocal; + } + + /** + * Sends given mail template to all addresses found in email wrapper + *

+ * @param template Template to send + * @param context Velocity context + * @param emailWrapper Email wrapper containing recipient and such + * @param mailSession Mail session + *

+ * @throws MessagingException If something happened on message delivery + */ + protected void sendMailTemplate (final Template template, final VelocityContext context, final WrapableEmailDelivery emailWrapper, final Session mailSession) throws MessagingException { + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("sendMailTemplate: template={0},emailWrapper={1},mailSession={2} - CALLED!", template, emailWrapper, mailSession)); //NOI18N + + // The parameters must be valid + if (null == template) { + // Throw NPE + throw new NullPointerException("template is null"); //NOI18N + } else if (null == emailWrapper) { + // Throw NPE + throw new NullPointerException("emailWrapper is null"); //NOI18N + } else if (emailWrapper.getRecipient() == null) { + // Throw NPE again + throw new NullPointerException("emailWrapper.recipient is null"); //NOI18N + } else if (emailWrapper.getSubjectLine() == null) { + // ... and again + throw new NullPointerException("emailWrapper.subjectLine is null"); //NOI18N + } else if (emailWrapper.getSubjectLine().isEmpty()) { + // Is empty + throw new IllegalArgumentException("emailWrapper.subjectLine is empty"); //NOI18N + } else if (emailWrapper.getTemplateName() == null) { + // ... and again + throw new NullPointerException("emailWrapper.templateName is null"); //NOI18N + } else if (emailWrapper.getTemplateName().isEmpty()) { + // Is empty + throw new IllegalArgumentException("emailWrapper.templateName is empty"); //NOI18N + } else if (emailWrapper.getLocale()== null) { + // Throw NPE again + throw new NullPointerException("emailWrapper.locale is null"); //NOI18N + } + + // Get writer instance + StringWriter writer = new StringWriter(); + + // Merge template + template.merge(context, writer); + + // Get all out and send it + this.sendMail(emailWrapper.getRecipient(), emailWrapper.getSubjectLine(), writer.toString(), mailSession); + } + } diff --git a/src/org/mxchange/jmailee/model/delivery/DeliverableEmail.java b/src/org/mxchange/jmailee/model/delivery/DeliverableEmail.java index 0cc7685..6c83433 100644 --- a/src/org/mxchange/jmailee/model/delivery/DeliverableEmail.java +++ b/src/org/mxchange/jmailee/model/delivery/DeliverableEmail.java @@ -17,6 +17,7 @@ package org.mxchange.jmailee.model.delivery; import java.io.Serializable; +import org.apache.velocity.app.VelocityEngine; /** * An interface for email delivery classes @@ -25,4 +26,11 @@ import java.io.Serializable; */ public interface DeliverableEmail extends Serializable { + /** + * Getter for template engine + *

+ * @return Template engine + */ + VelocityEngine getTemplateEngine (); + } diff --git a/src/org/mxchange/jmailee/model/delivery/wrapper/EmailDeliveryWrapper.java b/src/org/mxchange/jmailee/model/delivery/wrapper/EmailDeliveryWrapper.java index 89d4978..788c1a0 100644 --- a/src/org/mxchange/jmailee/model/delivery/wrapper/EmailDeliveryWrapper.java +++ b/src/org/mxchange/jmailee/model/delivery/wrapper/EmailDeliveryWrapper.java @@ -16,7 +16,9 @@ */ package org.mxchange.jmailee.model.delivery.wrapper; +import java.util.Locale; import java.util.Properties; +import javax.mail.Address; /** * A wrapper class for email delivery. @@ -31,103 +33,80 @@ public class EmailDeliveryWrapper implements WrapableEmailDelivery { private static final long serialVersionUID = 518_209_689_877_185_914L; /** - * Body of email + * Locale instance for language */ - private String body; + private Locale locale; /** * Recipient email address */ - private String emailAddress; + private Address recipient; /** - * (Optional) properties + * Subject line */ - private Properties[] properties; + private String subjectLine; /** - * Subject line + * Template name */ - private String subjectLine; + private String templateName; /** - * Constructor with email address (recipient), subject line, body and - * optional properties - * - * @param emailAddress Recipient's email address - * @param subjectLine Subject line - * @param body Body content - * @param properties Optional properties to e.g. override from address + * Template variables */ - public EmailDeliveryWrapper (final String emailAddress, final String subjectLine, final String body, final Properties[] properties) { - // Check all except properties as they are optional - if (null == emailAddress) { - // Throw NPE - throw new NullPointerException("emailAddress is null"); //NOI18N - } else if (emailAddress.trim().isEmpty()) { - // Is empty - throw new IllegalArgumentException("emailAddress is empty"); //NOI18N - } else if (null == subjectLine) { - // Throw NPE - throw new NullPointerException("subjectLine is null"); //NOI18N - } else if (subjectLine.trim().isEmpty()) { - // Is empty - throw new IllegalArgumentException("subjectLine is empty"); //NOI18N - } else if (null == body) { - // Throw NPE - throw new NullPointerException("body is null"); //NOI18N - } else if (body.trim().isEmpty()) { - // Is empty - throw new IllegalArgumentException("body is empty"); //NOI18N - } - - // Then set all - this.emailAddress = emailAddress; - this.subjectLine = subjectLine; - this.body = body; - this.properties = properties; + private Properties templateVariables; + + @Override + public Locale getLocale () { + return this.locale; } @Override - public String getBody () { - return this.body; + public void setLocale (final Locale locale) { + this.locale = locale; } @Override - public void setBody (final String body) { - this.body = body; + public Address getRecipient () { + return this.recipient; } @Override - public String getEmailAddress () { - return this.emailAddress; + public void setRecipient (final Address recipient) { + this.recipient = recipient; } @Override - public void setEmailAddress (final String emailAddress) { - this.emailAddress = emailAddress; + public String getSubjectLine () { + return this.subjectLine; } @Override - @SuppressWarnings ("ReturnOfCollectionOrArrayField") - public Properties[] getProperties () { - return this.properties; + public void setSubjectLine (final String subjectLine) { + this.subjectLine = subjectLine; } @Override - @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter") - public void setProperties (final Properties[] properties) { - this.properties = properties; + public String getTemplateName () { + return this.templateName; } @Override - public String getSubjectLine () { - return this.subjectLine; + public void setTemplateName (final String templateName) { + this.templateName = templateName; } @Override - public void setSubjectLine (final String subjectLine) { - this.subjectLine = subjectLine; + @SuppressWarnings ("ReturnOfCollectionOrArrayField") + public Properties getTemplateVariables () { + return this.templateVariables; + } + + @Override + @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter") + public void setTemplateVariables (final Properties templateVariables) { + this.templateVariables = templateVariables; } } diff --git a/src/org/mxchange/jmailee/model/delivery/wrapper/WrapableEmailDelivery.java b/src/org/mxchange/jmailee/model/delivery/wrapper/WrapableEmailDelivery.java index 36a460e..fb31459 100644 --- a/src/org/mxchange/jmailee/model/delivery/wrapper/WrapableEmailDelivery.java +++ b/src/org/mxchange/jmailee/model/delivery/wrapper/WrapableEmailDelivery.java @@ -17,7 +17,9 @@ package org.mxchange.jmailee.model.delivery.wrapper; import java.io.Serializable; +import java.util.Locale; import java.util.Properties; +import javax.mail.Address; /** * A generic wrapper interface for mail delivery. @@ -27,46 +29,46 @@ import java.util.Properties; public interface WrapableEmailDelivery extends Serializable { /** - * Getter for body + * Getter fo template name *

- * @return Body + * @return Template name */ - String getBody (); + String getTemplateName (); /** - * Setter for body + * Setter fo template name *

- * @param body Body + * @param templateName Template name */ - void setBody (final String body); + void setTemplateName (final String templateName); /** - * Getter for recipient's email address + * Getter for recipient email address *

- * @return Recipient's email address + * @return Email address recipient */ - String getEmailAddress (); + Address getRecipient (); /** - * Setter for recipient's email address + * Setter for recipient email address *

- * @param emailAddress Recipient's email address + * @param recipient Email address recipient */ - void setEmailAddress (final String emailAddress); + void setRecipient (final Address recipient); /** * Getter for optional properties *

* @return Optional properties */ - Properties[] getProperties (); + Properties getTemplateVariables (); /** * Setter for optional properties *

* @param properties Optional properties */ - void setProperties (final Properties[] properties); + void setTemplateVariables (final Properties properties); /** * Getter for subject line @@ -82,4 +84,18 @@ public interface WrapableEmailDelivery extends Serializable { */ void setSubjectLine (final String subjectLine); + /** + * Getter for locale + *

+ * @return Locale instance + */ + Locale getLocale (); + + /** + * Setter for locale + *

+ * @param locale Locale instance + */ + void setLocale (final Locale locale); + } -- 2.39.2