/******************************************************************************* * Australian National University Data Commons * Copyright (C) 2013 The Australian National University * * This file is part of Australian National University Data Commons. * * Australian National University Data Commons is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later * version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package au.edu.anu.datacommons.collectionrequest; import static java.text.MessageFormat.format; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.regex.Pattern; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; import au.edu.anu.datacommons.config.Config; import au.edu.anu.datacommons.properties.GlobalProps; import au.edu.anu.datacommons.util.Util; /** * Represents an email object comprising of from email, to email(s), subject and body. * * @author Rahul Khanna * */ public class Email { private static final Logger LOGGER = LoggerFactory.getLogger(Email.class); // Regular expression to check for a valid email address. // Source: http://www.regular-expressions.info/email.html private static final Pattern pattern = Pattern .compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"); private JavaMailSenderImpl mailSender; private String fromName; private String fromEmail; private Map<String, String> recipients; private String subject; private String body; public Email(JavaMailSenderImpl mailSender) { this.mailSender = mailSender; this.setFromName("ANU Data Commons"); this.setFromEmail("no-reply@anu.edu.au"); this.recipients = new HashMap<String, String>(); } public String getFromName() { return fromName; } public void setFromName(String fromName) { this.fromName = fromName; } public String getFromEmail() { return fromEmail; } public void setFromEmail(String fromEmail) { if (!isValidEmail(fromEmail)) { LOGGER.warn("Potentially invalid email address - {}", fromEmail); } this.fromEmail = fromEmail; } public Map<String, String> getRecipients() { return recipients; } public void addRecipient(String toEmail) { addRecipient(toEmail, null); } public void addRecipient(String toEmail, String name) { if (!isValidEmail(toEmail)) { LOGGER.warn("Potentially invalid email address - {}", toEmail); } recipients.put(toEmail, name); } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public void setBody(String templateFilename, Map<String, String> vars) throws IOException { // Read the template file with variables as ${varname} which will be replaced with the value against the key in // the Map. this.body = convertStreamToString(Thread.currentThread().getContextClassLoader() .getResourceAsStream(templateFilename)); for (String iVar : vars.keySet()) { this.body = this.body.replaceAll("\\$\\{" + iVar + "\\}", vars.get(iVar)); } } /** * Creates a SimpleMailMessage object from the data provided previously. Sends that SimpleMailMessage object using * the {@link JavaMailSenderImpl} sender */ public void send() { if (Boolean.parseBoolean(GlobalProps.getProperty(GlobalProps.PROP_EMAIL_DEBUG_SEND, "false"))) { if (mailSender == null) { throw new NullPointerException("mailSender is null"); } if (!Util.isNotEmpty(this.subject)) { throw new NullPointerException("Subject is null. A subject must be provided."); } if (!Util.isNotEmpty(this.body)) { throw new NullPointerException("Message Body is Null. Message text must be provided."); } SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(format("{0} <{1}>", fromName, fromEmail)); message.setTo(getRecipientsAsStringArray()); message.setSubject(subject); message.setText(body); LOGGER.info("Sending email...\r\nTO: {}\r\nSUBJECT: {}\r\nBODY: {}", new Object[] { recipientsAsString(), subject, body }); mailSender.send(message); } else { LOGGER.info( "email.debug.sendmail set to 'false' or not present in Global Properties. Following email not sent out.\r\nTO: {}\r\nSUBJECT: {}\r\nBODY: {}", new Object[] { recipientsAsString(), subject, body }); } } private String recipientsAsString() { StringBuilder toList = new StringBuilder(); String[] toListArray = getRecipientsAsStringArray(); for (int i = 0; i < toListArray.length; i++) { toList.append(toListArray[i]); if (i < (toListArray.length - 1)) { toList.append(", "); } } return toList.toString(); } private String[] getRecipientsAsStringArray() { Set<String> emailSet = new HashSet<String>(recipients.size()); for (Entry<String, String> recipient : recipients.entrySet()) { if (recipient.getValue() != null) { emailSet.add(format("{0} <{1}>", recipient.getValue(), recipient.getKey())); } else { emailSet.add(recipient.getKey()); } } return emailSet.toArray(new String[0]); } private String convertStreamToString(InputStream is) throws IOException { if (is == null) { throw new NullPointerException("InputStream is null."); } Writer writer = new StringWriter(); char[] buffer = new char[8192]; // 8K. try { BufferedReader reader = new BufferedReader(new InputStreamReader(is, Config.CHARSET)); int n; while ((n = reader.read(buffer)) != -1) { writer.write(buffer, 0, n); } } finally { IOUtils.closeQuietly(is); } return writer.toString(); } /** * Checks if an email address is valid. * * @param email * Email address to check as String * @return true if valid, false otherwise */ public static boolean isValidEmail(String email) { return pattern.matcher(email).matches(); } }