com.databasesandlife.util
Class EmailTemplate

java.lang.Object
  extended by com.databasesandlife.util.EmailTemplate

public class EmailTemplate
extends Object

Represents a directory in the classpath, which contains text and potentially graphics, in multiple languages and multiple formats, for outgoing notification emails.

A directory within the classpath should be created, and filled with the following files:

Concerning languages, although e.g. "subject.utf8.txt" must be present, there may also be files with names such as "subject_de.utf8.txt" files for other Locales.

One or both of the plain-text and HTML versions of the email must be present. If they are both present then a "multipart/alternative" email is sent.

Bodies and subjects may have variables such ${XYZ}. All variables are HTML-escaped in the HTML version of the email apart from variables with names such as ${XYZ_HTML}.

For unit testing, use the static method setLastBodyForTestingInsteadOfSendingEmails(). After that method has been called, no emails will be sent, instead the method getLastBodyForTesting() may be used to retrieve the last sent plain/text email body. This allows one to assert that particular emails would be sent, and that they contain particular text.

Writing code such as new EmailTemplate("myproject.mtpl.registration") has the disadvantage that if that package is renamed, refactoring tools will not see this string, and not rename it. Errors will result at run-time. The solution is to create a class in the directory, which calls its superclass constructor with its package name. This class is then instanciated in the client code, instead of the general EmailTemplate.

You can send attachments with your email (e.g. PDF invoices) by passing multiple EmailTemplate.Attachment objects to the send method. Either you implement your own attachment, providing the filename, mime type and a way to get an InputStream for the bytes of the attachment, or you can just create a EmailTemplate.ByteArrayAttachment by passing the filename, mime type and a byte[].

Concerning naming,

Usage

In the directory containing the template files:

class RegistrationEmailTemplate extends EmailTemplate {
   public RegistrationEmailTemplate() {
     super(RegistrationEmailTemplate.class.getPackage());
   }
   // other methods can be added, specific to this email template
}

In client code:

class RegistrationProcess {
  public registerNewUser(InternetAddress emailAddress, Locale language, String name, ... ) {
    String smtpServer = "localhost";
    EmailTransaction tx = new EmailTransaction(smtpServer);

    Map<String,String> params = new HashMap<String,String>();
    params.put("USERNAME", name);

    RegistrationEmailTemplate tpl = new RegistrationEmailTemplate();
    tpl.send(tx, recipientEmailAddress, language, params);

    tx.commit();
  }
}

In unit test code:

class RegistrationProcessTest extends TestCase {
  public testRegisterNewUser() {
    EmailTemplate.setLastBodyForTestingInsteadOfSendingEmails();
    new RegistrationProcess().registerNewUser("test@example.com", "Adrian");
    String txt = EmailTemplate.getLastBodyForTesting();
    assertTrue(txt.contains("Adrian"));
  }
}

Version:
$Revision: 6374 $
Author:
The Java source is copyright Adrian Smith and licensed under the LGPL 3.

Nested Class Summary
static interface EmailTemplate.Attachment
           
static class EmailTemplate.ByteArrayAttachment
           
static class EmailTemplate.FileNotFoundInEmailTemplateDirectoryException
           
 
Constructor Summary
EmailTemplate(Package pkg)
           
EmailTemplate(String pkgStr)
           
 
Method Summary
static String getLastBodyForTesting()
          Return the plain text body of the last email which has been sent; or the empty string in case no emails have been sent.
static String replacePlainTextParameters(String template, Map<String,String> parameters)
          Replaces variables such as ${XYZ} in the template.
 void send(EmailTransaction tx, javax.mail.internet.InternetAddress recipientEmailAddress, Locale locale, Map<String,String> parameters, EmailTemplate.Attachment... attachments)
          Send an email based on this email template.
static void setLastBodyForTestingInsteadOfSendingEmails()
          Henceforth, no emails will be sent; instead the body will be recorded for inspection by getLastBodyForTesting().
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

EmailTemplate

public EmailTemplate(Package pkg)

EmailTemplate

public EmailTemplate(String pkgStr)
Method Detail

setLastBodyForTestingInsteadOfSendingEmails

public static void setLastBodyForTestingInsteadOfSendingEmails()
Henceforth, no emails will be sent; instead the body will be recorded for inspection by getLastBodyForTesting().


getLastBodyForTesting

public static String getLastBodyForTesting()
Return the plain text body of the last email which has been sent; or the empty string in case no emails have been sent.


replacePlainTextParameters

public static String replacePlainTextParameters(String template,
                                                Map<String,String> parameters)
Replaces variables such as ${XYZ} in the template. Variables which are not found remain in their original unreplaced form.


send

public void send(EmailTransaction tx,
                 javax.mail.internet.InternetAddress recipientEmailAddress,
                 Locale locale,
                 Map<String,String> parameters,
                 EmailTemplate.Attachment... attachments)
Send an email based on this email template.