/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* bstefanescu
*/
package org.eclipse.ecr.automation.core.mail;
import java.io.InputStream;
import java.util.Properties;
import javax.mail.Authenticator;
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 javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
*/
public class Mailer {
private static final Log log = LogFactory.getLog(Mailer.class);
protected Properties config;
protected volatile Session session;
protected Authenticator auth;
/**
* The JNDI session name. If not null JNDI will be used to lookup the
* default session, otherwise local configuration (through {@link #config})
* will be used to create a session.
*/
protected final String sessionName;
/**
* Create a mailer that can be configured using the API.
*
* @see #setAuthenticator(Authenticator)
* @see #setCredentials(String, String)
* @see #setServer(String)
*/
public Mailer() {
this(null, new Properties());
}
/**
* Create a mailer that use the given properties to configure the session.
*
* @param config
*/
public Mailer(Properties config) {
this(null, config);
}
/**
* Create a mailer using a session that lookup for the session in JNDI
* under the given session name.
*
* @param sessionName
*/
public Mailer(String sessionName) {
this(sessionName, new Properties());
}
/**
* Create a mailer using a session that lookup for the session in JNDI
* under the given session name. If the JNDI binding doesn't exists use the
* given properties to cinfiugure the session.
*
* @param sessionName
* @param config
*/
public Mailer(String sessionName, Properties config) {
this.config = config;
this.sessionName = sessionName;
final String user = config.getProperty("mail.smtp.user");
final String pass = config.getProperty("mail.smtp.password");
if (user != null && pass != null) {
setAuthenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
});
}
}
public void setServer(String host) {
setServer(host, "25", false);
}
public void setServer(String host, boolean ssl) {
setServer(host, ssl ? "465" : "25", ssl);
}
/**
* Set the SMTP server address to use
*
* @param host
* @param port
*/
public void setServer(String host, String port) {
setServer(host, port, false);
}
public void setServer(String host, String port, boolean ssl) {
if (ssl) {
if (port == null) {
port = "465";
}
config.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
config.put("mail.smtp.socketFactory.fallback", "false");
config.put("mail.smtp.socketFactory.port", port);
} else if (port == null) {
port = "25";
}
config.setProperty("mail.smtp.host", host);
config.setProperty("mail.smtp.port", port);
session = null;
}
/**
* Set SMTP credential
*
* @param user
* @param pass
*/
public void setCredentials(final String user, final String pass) {
config.setProperty("mail.smtp.auth", "true");
this.auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
};
session = null;
}
public void setAuthenticator(Authenticator auth) {
config.setProperty("mail.smtp.auth", "true");
this.auth = auth;
session = null;
}
public void setDebug(boolean debug) {
config.setProperty("mail.debug", Boolean.toString(debug));
}
public Session getSession() {
if (session == null) {
synchronized (this) {
if (session == null) {
if (sessionName != null) {
try {
InitialContext ic = new InitialContext();
session = (Session) ic.lookup(sessionName);
} catch (NamingException e) {
log.warn("Failed to lookup mail session using JNDI name "
+ sessionName
+ ". Falling back on local configuration.");
session = Session.getInstance(config, auth);
}
} else {
session = Session.getInstance(config, auth);
}
}
}
}
return session;
}
public Properties getConfiguration() {
return config;
}
public void setConfiguration(Properties config) {
this.config = config;
}
public void loadConfiguration(InputStream in) throws Exception {
config.load(in);
}
public void send(MimeMessage message) throws MessagingException {
Transport.send(message);
}
public Message newMessage() {
return new Message(getSession());
}
/**
* Send a single email.
*/
public void sendEmail(String from, String to, String subject, String body)
throws MessagingException {
// Here, no Authenticator argument is used (it is null).
// Authenticators are used to prompt the user for user
// name and password.
MimeMessage message = new MimeMessage(getSession());
// the "from" address may be set in code, or set in the
// config file under "mail.from" ; here, the latter style is used
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
}
public static class Message extends MimeMessage {
public Message(Session session) {
super(session);
}
public Message(Session session, InputStream in)
throws MessagingException {
super(session, in);
}
public Message addTo(String to) throws MessagingException {
addRecipient(RecipientType.TO, new InternetAddress(to));
return this;
}
public Message addCc(String cc) throws MessagingException {
addRecipient(RecipientType.CC, new InternetAddress(cc));
return this;
}
public Message addBcc(String bcc) throws MessagingException {
addRecipient(RecipientType.BCC, new InternetAddress(bcc));
return this;
}
public Message addFrom(String from) throws MessagingException {
addFrom(new InternetAddress[] { new InternetAddress(from) });
return this;
}
public Message setFrom(String from) throws MessagingException {
setFrom(new InternetAddress(from));
return this;
}
public void send() throws MessagingException {
Transport.send(this);
}
}
}