package pl.net.bluesoft.rnd.pt.utils.template; import freemarker.cache.TemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import pl.net.bluesoft.rnd.processtool.template.ProcessToolNotificationTemplate; import pl.net.bluesoft.rnd.processtool.template.ProcessToolTemplateLoader; import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.logging.Logger; public class TemplateProcessor { public static final String DEFAULT_SUBJECT_SUFFIX = "___subject"; public static final long DEFAULT_CONFIG_CACHE_REFRESH_INTERVAL = 60 * 1000; private static final Logger logger = Logger.getLogger(TemplateProcessor.class.getName()); private String subjectSuffix = DEFAULT_SUBJECT_SUFFIX; private long cacheRefreshInterval = DEFAULT_CONFIG_CACHE_REFRESH_INTERVAL; private Configuration freemarkerConfiguration; private Map<String, ProcessToolNotificationTemplate> templateMap = new HashMap<String, ProcessToolNotificationTemplate>(); private Map<String, String> templateCache = new HashMap<String, String>(); private long cacheUpdateTime = 0; private ProcessToolTemplateLoader templateLoader; public TemplateProcessor(ProcessToolTemplateLoader templateLoader) { if (templateLoader == null) { throw new IllegalArgumentException("Cannot create the template processor without a template loader!"); } this.templateLoader = templateLoader; } public void processEmail(String templateName, Map dataModel, String recipient, final Properties mailProperties, boolean sendHtml) throws IOException, TemplateException, MessagingException { refreshTemplates(); String body = processTemplate(templateName, dataModel); String subject = processTemplate(templateName + getSubjectSuffix(), dataModel); ProcessToolNotificationTemplate template = templateMap.get(templateName); Session mailSession = Session.getDefaultInstance(mailProperties, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(mailProperties.getProperty("mail.smtp.user"), mailProperties.getProperty("mail.smtp.password")); } }); sendEmail(recipient, template.getSender(), subject, body, sendHtml, mailSession); } public void sendEmail(String rcpt, String from, String subject, String body, boolean sendHtml, Session mailSession) throws MessagingException { Message message = new MimeMessage(mailSession); message.setFrom(new InternetAddress(from)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(rcpt)); message.setSubject(subject); message.setContent(body, sendHtml ? "text/html" : "text/plain"); Transport.send(message); } public String processTemplate(String templateName, Map dataModel) throws IOException, TemplateException { logger.info("Using template " + templateName); Template template = getFreemarkerConfiguration().getTemplate(templateName); StringWriter sw = new StringWriter(); template.process(dataModel, sw); sw.flush(); return sw.toString(); } private synchronized Configuration getFreemarkerConfiguration() { return freemarkerConfiguration; } public synchronized void refreshTemplates() { if (cacheUpdateTime + getCacheRefreshInterval() < System.currentTimeMillis()) { List<ProcessToolNotificationTemplate> templates = templateLoader.loadTemplates(); for (ProcessToolNotificationTemplate template : templates) { templateMap.put(template.getTemplateName(), template); templateCache.put(template.getTemplateName(), template.getBodyTemplate()); templateCache.put(template.getTemplateName() + DEFAULT_SUBJECT_SUFFIX, template.getSubjectTemplate()); } freemarkerConfiguration = new Configuration(); freemarkerConfiguration.setTemplateLoader(new TemplateLoader() { @Override public Object findTemplateSource(String name) throws IOException { return templateCache.containsKey(name) ? templateCache.get(name) : null; } @Override public long getLastModified(Object templateSource) { return 0; } @Override public Reader getReader(Object templateSource, String encoding) throws IOException { if (templateSource == null) { return null; } return new StringReader(((String) templateSource)); } @Override public void closeTemplateSource(Object templateSource) throws IOException { } }); cacheUpdateTime = System.currentTimeMillis(); } } public String getSubjectSuffix() { return subjectSuffix; } public void setSubjectSuffix(String subjectSuffix) { this.subjectSuffix = subjectSuffix; } public long getCacheRefreshInterval() { return cacheRefreshInterval; } public void setCacheRefreshInterval(long cacheRefreshInterval) { this.cacheRefreshInterval = cacheRefreshInterval; } }