Skip to content

Instantly share code, notes, and snippets.

@jweyrich
Last active December 14, 2016 13:38
Show Gist options
  • Save jweyrich/7896735 to your computer and use it in GitHub Desktop.
Save jweyrich/7896735 to your computer and use it in GitHub Desktop.
Example of a Quartz job that sends email notifications using FreeMarker templates from an application built with VRaptor. Dependencies: - vraptor-3.5.3 - vraptor-tasks-1.1.0 - vraptor-freemarker-1.1.2
package ...;
import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.Container;
import br.com.caelum.vraptor.tasks.scheduler.Scheduled;
import br.com.caelum.vraptor.tasks.Task;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Jardel Weyrich
*/
@ApplicationScoped
@Scheduled(
initialDelay = AdminNotifierTask.STARTS_IN * 60 * 1000, // 2 minutes
fixedRate = AdminNotifierTask.REPEAT_EVERY * 60 * 1000, // 2 minutes
concurrent = false
)
public class AdminNotifierTask implements Task {
public static final int STARTS_IN = 2; // minutes
public static final int REPEAT_EVERY = 2; // minutes
private static final Logger log = LoggerFactory.getLogger(AdminNotifierTask.class);
private Container container;
public AdminNotifierTask(Container container) {
this.container = container;
}
@Override
public void execute() {
List<Event> pendingEvents = findAllPending();
if (pendingEvents == null || pendingEvents.isEmpty()) {
log.info("There are no pending events");
return;
}
log.info(String.format("Found %d pending events.", pendingEvents.size()));
final EventsEmailNotifier notifier = new EventsEmailNotifier(this.container);
for (Event pe : pendingEvents) {
boolean succeeded = notifier.notifyPendingEvent(pe);
if (succeeded) {
pe.setDidSendPendingNotification(true);
}
}
}
private List<Event> findAllPending() {
// ...
}
}
package ...;
import br.com.caelum.vraptor.core.Localization;
import br.com.caelum.vraptor.environment.Environment;
import br.com.caelum.vraptor.freemarker.Freemarker;
import br.com.caelum.vraptor.freemarker.FreemarkerConfiguration;
import br.com.caelum.vraptor.freemarker.Template;
import br.com.caelum.vraptor.ioc.Container;
import br.com.caelum.vraptor.simplemail.Mailer;
import br.com.caelum.vraptor.simplemail.template.DefaultTemplateMailer;
import br.com.caelum.vraptor.simplemail.template.TemplateMailer;
import br.com.caelum.vraptor.util.test.MockLocalization;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Jardel Weyrich
*/
public final class EventsEmailNotifier {
private static final Logger log = LoggerFactory.getLogger(EventsEmailNotifier.class);
private Container container;
private Environment environment;
private ServletContext context;
private Mailer mailer; // We cannot use AsyncMailer here because of its dependencies.
private Freemarker freemarker;
private Localization localization;
private TemplateMailer templates;
public EventsEmailNotifier(Container container) {
this.container = container;
this.environment = this.container.instanceFor(Environment.class);
this.context = this.container.instanceFor(ServletContext.class); // This is @ApplicationScoped so that's ok.
this.mailer = this.container.instanceFor(Mailer.class);
final FreemarkerConfiguration cfg = this.container.instanceFor(FreemarkerConfiguration.class);
this.freemarker = new CustomFreemarkerEngine(cfg);
this.localization = new MockLocalization(); // FIXME: This is ugly as hell.
this.templates = new DefaultTemplateMailer(
this.localization, this.freemarker, this.context, this.environment);
}
// Adapted from br.com.caelum.vraptor.freemarker.FreemarkerEngine
public final class CustomFreemarkerEngine implements Freemarker {
private final FreemarkerConfiguration cfg;
public CustomFreemarkerEngine(FreemarkerConfiguration cfg) {
this.cfg = cfg;
}
@Override
public Template use(String name) throws IOException {
freemarker.template.Template template = cfg.getConfiguration().getTemplate(name + ".ftl");
return new CustomDefaultTemplate(template);
}
}
// Adapted from br.com.caelum.vraptor.freemarker.DefaultTemplate
public final class CustomDefaultTemplate implements Template {
private final freemarker.template.Template template;
private final Map<String, Object> root = new HashMap<>();
public CustomDefaultTemplate(freemarker.template.Template template) {
this.template = template;
}
@Override
public void render() throws IOException, TemplateException {
// Disable render to servlet response
throw new UnsupportedOperationException();
}
@Override
public Template with(String key, Object value) {
root.put(key, value);
return this;
}
@Override
public String getContent() throws IOException, TemplateException {
StringWriter writer = new StringWriter();
freemarker.core.Environment processingEnv = template.createProcessingEnvironment(root, writer);
processingEnv.setOutputEncoding("UTF-8");
processingEnv.process();
writer.flush();
return writer.getBuffer().toString();
}
}
// NOTE: One would prefer to use events and listeners. Example:
// @Inject @Any private Event<Something> somethingEvent;
// public void eventFired(@Observes Something something) { /* ... */ }
public boolean notifyPendingEvent(final Event event) {
final String toName = "Admin"
final String toEmail = "root@localhost";
final String subject = "Test";
final Email email = this.templates
.template("test_email_template")
.to(toName, toEmail);
email.setSubject(subject);
try {
mailer.send(email);
} catch (EmailException ex) {
log.error(null, ex);
return false;
}
return true;
}
}
@priyaprashanth
Copy link

want to Build Notifier Servlet using Email templates can some one help me on this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment