org.nuxeo.ecm.automation.core.mail.Mailer.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.automation.core.mail.Mailer.java

Source

/*
 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     bstefanescu
 */
package org.nuxeo.ecm.automation.core.mail;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.mail.Address;
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");
        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 IOException {
        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(javax.mail.Message.RecipientType.TO, new InternetAddress(to));
        message.setSubject(subject);
        message.setText(body);
        Transport.send(message);
    }

    public static class Message extends MimeMessage {

        public static enum AS {
            FROM, TO, CC, BCC, REPLYTO
        }

        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(javax.mail.Message.RecipientType.TO, new InternetAddress(to));
            return this;
        }

        public Message addCc(String cc) throws MessagingException {
            addRecipient(javax.mail.Message.RecipientType.CC, new InternetAddress(cc));
            return this;
        }

        public Message addBcc(String bcc) throws MessagingException {
            addRecipient(javax.mail.Message.RecipientType.BCC, new InternetAddress(bcc));
            return this;
        }

        public Message addFrom(String from) throws MessagingException {
            addFrom(new InternetAddress[] { new InternetAddress(from) });
            return this;
        }

        public void addInfoInMessageHeader(String address, AS as) throws MessagingException {
            switch (as) {
            case FROM:
                addFrom(address);
                break;
            case TO:
                addTo(address);
                break;
            case CC:
                addCc(address);
                break;
            case BCC:
                addBcc(address);
                break;
            case REPLYTO:
                Address[] oldValue = getReplyTo();
                Address[] replyToValue;
                if (getReplyTo() == null) {
                    replyToValue = new Address[1];
                } else {
                    replyToValue = new Address[oldValue.length + 1];
                }
                for (int i = 0; i < oldValue.length; i++) {
                    replyToValue[i] = oldValue[i];
                }
                replyToValue[oldValue.length] = new InternetAddress(address);
                setReplyTo(replyToValue);
                break;
            default:
                throw new MessagingException("Unknown header info " + as.toString());
            }
        }

        public Message setFrom(String from) throws MessagingException {
            setFrom(new InternetAddress(from));
            return this;
        }

        public void send() throws MessagingException {
            Transport.send(this);
        }

    }

}