/* Copyright (c) 2012 GeoSolutions http://www.geo-solutions.it. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.mail;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.io.IOUtils;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geotools.util.logging.Logging;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* The Class SendMail.
*
* @author "Alessio Fabiani - alessio.fabiani@geo-solutions.it"
*/
public class SendMail {
/** The props. */
private Properties props;
/** The conf. */
private final MailConfiguration conf = new MailConfiguration();
private final static Logger LOGGER=Logging.getLogger(SendMail.class);
/** FreeMarker TEMPLATES *. */
static final Configuration TEMPLATES;
static {
TEMPLATES = new Configuration();
// same package of this class
try {
File templatesPath = getSendMailTemplatesPath();
if (templatesPath != null) {
TEMPLATES.setDirectoryForTemplateLoading(templatesPath);
} else {
TEMPLATES.setClassForTemplateLoading(SendMail.class, "");
}
} catch (IOException e) {
TEMPLATES.setClassForTemplateLoading(SendMail.class, "");
}
TEMPLATES.setObjectWrapper(new DefaultObjectWrapper());
}
/**
* Instantiates a new send mail.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public SendMail() throws IOException {
props = loadConfiguration();
}
/**
* Send an EMail to a specified address.
*
* @param address the to address
* @param subject the email address
* @param body message to send
* @throws MessagingException the messaging exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public void send(String address, String subject, String body){
try {
// Session session = Session.getDefaultInstance(props, null);
Session session = Session.getDefaultInstance(props, (conf.getMailSmtpAuth()
.equalsIgnoreCase("true") ? new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(conf.getUserName(), conf.getPassword());
}
} : null));
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(conf.getFromAddress(), conf.getFromAddressname()));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(address));
message.setSubject(subject);
message.setText(body.toString());
Transport.send(message);
} catch (Exception e) {
if(LOGGER.isLoggable(Level.SEVERE)){
LOGGER.log(Level.SEVERE,e.getLocalizedMessage(),e);
}
}
}
/**
* Send a notification to the specified address.
*
* @param toAddress the to address
* @param executiondId the executiond id
* @param expirationDelay
* @throws IOException Signals that an I/O exception has occurred.
* @throws MessagingException the messaging exception
*/
public void sendFinishedNotification(String toAddress, String executiondId, String result,
int expirationDelay){
try{
// load template for the password reset email
Template mailTemplate = TEMPLATES.getTemplate("FinishedNotificationMail.ftl");
StringWriter body = fillMailBody(toAddress, executiondId, result, expirationDelay,
mailTemplate);
send(toAddress, conf.getSubjet(), body.toString());
} catch (Exception e) {
if(LOGGER.isLoggable(Level.SEVERE)){
LOGGER.log(Level.SEVERE,e.getLocalizedMessage(),e);
}
}
}
/**
* Fill mail body.
*
* @param toAddress the to address
* @param executiondId the executiond id
* @param result
* @param expirationDelay
* @param mailTemplate the mail template
* @return the string writer
* @throws IOException Signals that an I/O exception has occurred.
*/
private StringWriter fillMailBody(String toAddress, String executiondId, String result,
int expirationDelay, Template mailTemplate) throws IOException {
// create template context
StringWriter body = new StringWriter();
Map<String, Object> templateContext = new HashMap<String, Object>();
templateContext.put("toAddress", toAddress);
templateContext.put("executiondId", executiondId);
String millis = String.format(
"%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(expirationDelay),
TimeUnit.MILLISECONDS.toSeconds(expirationDelay)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(expirationDelay)));
if (expirationDelay > 0) {
templateContext.put("expirationDelay", millis);
}
if (result != null) {
templateContext.put("result", result.toString());
}
// create message string
try {
mailTemplate.process(templateContext, body);
} catch (TemplateException e) {
throw new IOException(e);
}
return body;
}
/**
* Send started notification.
*
* @param toAddress the to address
* @param executiondId the executiond id
* @throws IOException Signals that an I/O exception has occurred.
* @throws MessagingException the messaging exception
*/
public void sendStartedNotification(String toAddress, String executiondId){
try {
// load template for the password reset email
Template mailTemplate = TEMPLATES.getTemplate("StartedNotificationMail.ftl");
StringWriter body = fillMailBody(toAddress, executiondId, null, 0, mailTemplate);
send(toAddress, conf.getSubjet(), body.toString());
} catch (Exception e) {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
}
}
/**
* Send started notification.
*
* @param toAddress the to address
* @param executiondId the executiond id
* @throws IOException Signals that an I/O exception has occurred.
* @throws MessagingException the messaging exception
*/
public void sendFailedNotification(String toAddress, String executiondId, String reason){
try {
// load template for failed error
Template mailTemplate = TEMPLATES.getTemplate("FailedNotificationMail.ftl");
// create template context
StringWriter body = new StringWriter();
Map<String, Object> templateContext = new HashMap<String, Object>();
templateContext.put("toAddress", toAddress);
templateContext.put("executiondId", executiondId);
templateContext.put("reason", reason);
// create message string
mailTemplate.process(templateContext, body);
send(toAddress, conf.getSubjet(), body.toString());
} catch (Exception e) {
if(LOGGER.isLoggable(Level.SEVERE)){
LOGGER.log(Level.SEVERE,e.getLocalizedMessage(),e);
}
}
}
/**
* Load configuration.
*
* @return the properties
* @throws IOException Signals that an I/O exception has occurred.
*/
public Properties loadConfiguration() throws IOException {
InputStream inputStream = null;
// load the inputStream using the Properties
try {
inputStream = new FileInputStream(new File(SendMail.getSendMailTemplatesPath()
.getParentFile(), "mail.properties"));
Properties properties = new Properties();
properties.load(inputStream);
conf.setMailSmtpHost(properties.getProperty("mail.smtp.host"));
conf.setMailSmtpSocketFactoryPort(properties
.getProperty("mail.smtp.socketFactory.port"));
conf.setMailSmtpFactoryClass(properties.getProperty("mail.smtp.socketFactory.class"));
conf.setMailSmtpAuth(properties.getProperty("mail.smtp.auth"));
conf.setMailSmtpPort(properties.getProperty("mail.smtp.port"));
conf.setUserName(properties.getProperty("username"));
conf.setPassword(properties.getProperty("password"));
conf.setFromAddress(properties.getProperty("fromAddress"));
conf.setFromAddressname(properties.getProperty("fromAddressname"));
conf.setSubjet(properties.getProperty("subject"));
conf.setBody(properties.getProperty("body"));
// get the value of the property
return properties;
} finally {
if (inputStream == null) {
IOUtils.closeQuietly(inputStream);
}
}
}
/**
*
* @return
* @throws IOException
*/
public static File getSendMailTemplatesPath() throws IOException {
// get the temporary storage for WPS
try {
GeoServerResourceLoader loader = GeoServerExtensions.bean(GeoServerResourceLoader.class);
File storage = new File(loader.getBaseDirectory().getCanonicalPath(), "/wps-cluster/templates");
return storage;
} catch (Exception e) {
throw new IOException("Could not find the data directory for WPS CLUSTER");
}
}
}