org.openmrs.module.sync.SyncMailUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.openmrs.module.sync.SyncMailUtil.java

Source

/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.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://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs.module.sync;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.GlobalProperty;
import org.openmrs.api.AdministrationService;
import org.openmrs.api.GlobalPropertyListener;
import org.openmrs.api.context.Context;
import org.openmrs.messagesource.MessageSourceService;
import org.openmrs.notification.MessageException;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Utility class for configuring and validating email settings, and sending emails
 */
public class SyncMailUtil implements GlobalPropertyListener {

    private static final Log log = LogFactory.getLog(SyncMailUtil.class);

    // ***** CONSTANTS *****

    public static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport_protocol";
    public static final String MAIL_SMTP_HOST = "mail.smtp_host";
    public static final String MAIL_SMTP_PORT = "mail.smtp_port";
    public static final String MAIL_SMTP_AUTH = "mail.smtp_auth";
    public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
    public static final String MAIL_USER = "mail.user";
    public static final String MAIL_PASSWORD = "mail.password";
    public static final String MAIL_DEFAULT_CONTENT_TYPE = "mail.default_content_type";
    public static final String MAIL_FROM = "mail.from";
    public static final String MAIL_DEBUG = "mail.debug";
    public static final String SYNC_ADMIN_EMAIL = "sync.admin_email";

    public static List<String> getMailGlobalProperties() {
        return Arrays.asList(MAIL_TRANSPORT_PROTOCOL, MAIL_SMTP_HOST, MAIL_SMTP_PORT, MAIL_SMTP_AUTH,
                MAIL_SMTP_STARTTLS_ENABLE, MAIL_USER, MAIL_PASSWORD, MAIL_DEFAULT_CONTENT_TYPE, MAIL_FROM,
                MAIL_DEBUG, SYNC_ADMIN_EMAIL);
    }

    //***** UTILITY METHODS

    /**
     * Cached mail session.  This is set to null and re-loaded anytime a mail global property changes
     */
    private static Session mailSession = null;

    /**
     * @return the currently configured email settings
     */
    public static Map<String, String> getCurrentlyConfiguredSettings() {
        AdministrationService adminService = Context.getAdministrationService();
        Map<String, String> settings = new LinkedHashMap<String, String>();
        for (String s : getMailGlobalProperties()) {
            settings.put(s, adminService.getGlobalProperty(s));
        }
        return settings;
    }

    /**
     * @return the currently cached mail session, or a new mail session if any mail configuration is changed
     */
    public static Session getMailSession() {
        if (mailSession == null) {
            mailSession = createSession(getCurrentlyConfiguredSettings());
        }
        return mailSession;
    }

    public static Session createSession(Map<String, String> settings) {
        Properties props = new Properties();
        props.setProperty("mail.transport.protocol", settings.get(MAIL_TRANSPORT_PROTOCOL));
        props.setProperty("mail.smtp.host", settings.get(MAIL_SMTP_HOST));
        props.setProperty("mail.smtp.port", settings.get(MAIL_SMTP_PORT));
        props.setProperty("mail.smtp.auth", settings.get(MAIL_SMTP_AUTH));
        props.setProperty("mail.smtp.starttls.enable", settings.get(MAIL_SMTP_STARTTLS_ENABLE));
        props.setProperty("mail.from", settings.get(MAIL_FROM));
        props.setProperty("mail.debug", settings.get(MAIL_DEBUG));

        final String mailUser = settings.get(MAIL_USER);
        final String mailPw = settings.get(MAIL_PASSWORD);

        Authenticator auth = new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(mailUser, mailPw);
            }
        };
        return Session.getInstance(props, auth);
    }

    public static String validateSettings(Map<String, String> settings) {
        MessageSourceService mss = Context.getMessageSourceService();
        try {
            Session session = createSession(settings);
            Transport transport = session.getTransport();
            transport.connect();
            transport.close();
            return mss.getMessage("sync.emailConfig.connectionSuccessful");
        } catch (Exception e) {
            return mss.getMessage("sync.emailConfig.connectionFailed") + ": " + e.getMessage();
        }
    }

    /**
     * Sends a message using the current mail session
     */
    public static void sendMessage(String recipients, String subject, String body) throws MessageException {
        try {
            Message message = new MimeMessage(getMailSession());
            message.setSentDate(new Date());
            if (StringUtils.isNotBlank(subject)) {
                message.setSubject(subject);
            }
            if (StringUtils.isNotBlank(recipients)) {
                for (String recipient : recipients.split("\\,")) {
                    message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipient));
                }
            }
            if (StringUtils.isNotBlank(body)) {
                Multipart multipart = new MimeMultipart();
                MimeBodyPart contentBodyPart = new MimeBodyPart();
                contentBodyPart.setContent(body, "text/html");
                multipart.addBodyPart(contentBodyPart);
                message.setContent(multipart);
            }
            log.info("Sending email with subject <" + subject + "> to <" + recipients + ">");
            log.debug("Mail has contents: \n" + body);
            Transport.send(message);
            log.debug("Message sent without errors");
        } catch (Exception e) {
            log.error("Message could not be sent due to " + e.getMessage(), e);
            throw new MessageException(e);
        }
    }

    @Override
    public boolean supportsPropertyName(String s) {
        return getMailGlobalProperties().contains(s);
    }

    @Override
    public void globalPropertyChanged(GlobalProperty globalProperty) {
        log.debug("Global property <" + globalProperty.getProperty() + "> changed, resetting mail session");
        mailSession = null;
    }

    @Override
    public void globalPropertyDeleted(String s) {
        log.debug("Global property <" + s + "> deleted, resetting mail session");
        mailSession = null;
    }
}