Java tutorial
/* * Computoser is a music-composition algorithm and a website to present the results * Copyright (C) 2012-2014 Bozhidar Bozhanov * * Computoser is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Computoser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Computoser. If not, see <http://www.gnu.org/licenses/>. */ package com.music.service; import java.io.Serializable; import java.io.StringWriter; import java.util.List; import java.util.Locale; import java.util.Map; import javax.inject.Inject; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.mail.Email; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.HtmlEmail; import org.apache.commons.mail.SimpleEmail; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.music.model.persistent.User; @Service public class EmailService { /** * Sends an email. No exception is thrown even if the message sending fails. * (This service may decide to reattempt sending after a while) * @param details */ private static final Logger logger = LoggerFactory.getLogger(EmailService.class); @Value("${smtp.host}") private String smtpHost; @Value("${smtp.user}") private String smtpUser; @Value("${smtp.password}") private String smtpPassword; @Value("${smtp.bounce.email}") private String smtpBounceEmail; @Value("${base.url}") private String baseUrl; @Inject private VelocityEngine engine; private Email createEmail(boolean html) { Email e = null; if (html) { e = new HtmlEmail(); } else { e = new SimpleEmail(); } e.setHostName(smtpHost); if (!StringUtils.isEmpty(smtpUser)) { e.setAuthentication(smtpUser, smtpPassword); } if (!StringUtils.isEmpty(smtpBounceEmail)) { e.setBounceAddress(smtpBounceEmail); } e.setTLS(true); e.setSmtpPort(587); //tls port e.setCharset("UTF8"); //e.setDebug(true); return e; } @Async public void send(EmailDetails details) { if (details.getSubject() == null || !BooleanUtils .xor(ArrayUtils.toArray(details.getMessage() != null, details.getMessageTemplate() != null))) { throw new IllegalStateException( "Either subject or subjectKey / either template/message/messageKey should be specified"); } Validate.notBlank(details.getFrom()); Email email = createEmail(details.isHtml()); String subject = constructSubject(details); email.setSubject(subject); String emailMessage = constructEmailMessages(details); try { if (details.isHtml()) { ((HtmlEmail) email).setHtmlMsg(emailMessage); } else { email.setMsg(emailMessage); } for (String to : details.getTo()) { email.addTo(to); } email.setFrom(details.getFrom()); email.send(); } catch (EmailException ex) { logger.error("Exception occurred when sending email to " + details.getTo(), ex); } } private String constructSubject(EmailDetails details) { String subject = ""; if (details.getSubject() != null) { subject = details.getSubject(); } return subject; } private String constructEmailMessages(EmailDetails details) { String emailMessage = null; if (details.getMessageTemplate() != null) { Template template = engine.getTemplate(details.getMessageTemplate(), "UTF-8"); StringWriter writer = new StringWriter(); Context ctx = new VelocityContext(); for (Map.Entry<String, Object> entry : details.getMessageTemplateModel().entrySet()) { ctx.put(entry.getKey(), entry.getValue()); } ctx.put("baseUrl", baseUrl); ctx.put("currentUser", details.getCurrentUser()); template.merge(ctx, writer); return writer.toString(); } if (details.getMessage() != null) { emailMessage = details.getMessage(); } return emailMessage; } public static class EmailDetails implements Serializable { private static final long serialVersionUID = 4456840962920327178L; private String from; private List<String> to = Lists.newArrayList(); private String messageTemplate; private Map<String, Object> messageTemplateModel = Maps.newHashMap(); private String subject; private String message; private String[] subjectParams = new String[0]; private String[] messageParams = new String[0]; private String[] extraMessageParams = new String[0]; private boolean html; private Locale locale = Locale.ENGLISH; private User currentUser; public String[] getSubjectParams() { return subjectParams; } public EmailDetails setSubjectParams(String[] sibjectParams) { this.subjectParams = sibjectParams; return this; } public String[] getMessageParams() { return messageParams; } public EmailDetails setMessageParams(String[] messageParams) { this.messageParams = messageParams; return this; } public boolean isHtml() { return html; } public EmailDetails setHtml(boolean html) { this.html = html; return this; } public Locale getLocale() { return locale; } public EmailDetails setLocale(Locale locale) { this.locale = locale; return this; } public String getFrom() { return from; } public EmailDetails setFrom(String from) { this.from = from; return this; } public List<String> getTo() { return to; } public EmailDetails setTo(String to) { this.to.clear(); return addTo(to); } public EmailDetails addTo(String to) { this.to.add(to); return this; } public String[] getExtraMessageParams() { return extraMessageParams; } public EmailDetails setExtraMessageParams(String[] extraMessageParams) { this.extraMessageParams = extraMessageParams; return this; } public String getSubject() { return subject; } public EmailDetails setSubject(String subject) { this.subject = subject; return this; } public String getMessage() { return message; } public EmailDetails setMessage(String message) { this.message = message; return this; } public String getMessageTemplate() { return messageTemplate; } public EmailDetails setMessageTemplate(String messageTemplate) { this.messageTemplate = messageTemplate; return this; } public Map<String, Object> getMessageTemplateModel() { return messageTemplateModel; } public EmailDetails setMessageTemplateModel(Map<String, Object> messageTemplateModel) { this.messageTemplateModel = messageTemplateModel; return this; } public EmailDetails addToMessageTemplateModel(String key, Object value) { messageTemplateModel.put(key, value); return this; } public User getCurrentUser() { return currentUser; } public EmailDetails setCurrentUser(User currentUser) { this.currentUser = currentUser; return this; } } }