com.ephesoft.dcma.mail.service.MailServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.ephesoft.dcma.mail.service.MailServiceImpl.java

Source

/********************************************************************************* 
* Ephesoft is a Intelligent Document Capture and Mailroom Automation program 
* developed by Ephesoft, Inc. Copyright (C) 2015 Ephesoft Inc. 
* 
* This program is free software; you can redistribute it and/or modify it under 
* the terms of the GNU Affero General Public License version 3 as published by the 
* Free Software Foundation with the addition of the following permission added 
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK 
* IN WHICH THE COPYRIGHT IS OWNED BY EPHESOFT, EPHESOFT DISCLAIMS THE WARRANTY 
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 
* 
* 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 Affero General Public License for more 
* details. 
* 
* You should have received a copy of the GNU Affero General Public License along with 
* this program; if not, see http://www.gnu.org/licenses or write to the Free 
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
* 02110-1301 USA. 
* 
* You can contact Ephesoft, Inc. headquarters at 111 Academy Way, 
* Irvine, CA 92617, USA. or at email address info@ephesoft.com. 
* 
* The interactive user interfaces in modified source and object code versions 
* of this program must display Appropriate Legal Notices, as required under 
* Section 5 of the GNU Affero General Public License version 3. 
* 
* In accordance with Section 7(b) of the GNU Affero General Public License version 3, 
* these Appropriate Legal Notices must retain the display of the "Ephesoft" logo. 
* If the display of the logo is not reasonably feasible for 
* technical reasons, the Appropriate Legal Notices must display the words 
* "Powered by Ephesoft". 
********************************************************************************/

package com.ephesoft.dcma.mail.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.StringUtils;

import com.ephesoft.dcma.core.common.MailMetaData;
import com.ephesoft.dcma.core.component.ICommonConstants;
import com.ephesoft.dcma.core.exception.DCMAApplicationException;
import com.ephesoft.dcma.da.domain.BatchInstance;
import com.ephesoft.dcma.mail.MailContentModel;
import com.ephesoft.dcma.mail.SendMailException;
import com.ephesoft.dcma.mail.constant.MailConstants;
import com.ephesoft.dcma.util.EphesoftStringUtil;

import freemarker.template.Configuration;

public class MailServiceImpl implements MailService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MailServiceImpl.class);

    /**
     * {@link String} mail id of the sender.
     */
    private String fromMail;

    /**
     * {@link String} mail id of the receiver.
     */
    private String toMail;
    private JavaMailSenderImpl mailSender;
    private Configuration freemarkerMailConfiguration;
    private boolean suppressMail;
    private static final String ORIGINAL_MAIL_MESSAGE = "\n\nErrorneous mail content Starts from here.\n\n";

    /**
     * Gets mail id of the sender.
     * 
     * @return {@link String}
     */
    public String getFromMail() {
        return fromMail;
    }

    /**
     * Sets mail id of the sender.
     * 
     * @param fromMail {@link String}
     */
    public void setFromMail(final String fromMail) {
        this.fromMail = fromMail;
    }

    /**
     * Gets mail id of the receiver.
     * 
     * @return {@link String}
     */
    public String getToMail() {
        return toMail;
    }

    /**
     * Sets mail id of the receiver.
     * 
     * @param toMail {@link String}
     */
    public void setToMail(final String toMail) {
        this.toMail = toMail;
    }

    public void setMailSender(final JavaMailSenderImpl mailSender) {
        this.mailSender = mailSender;
    }

    public void setFreemarkerMailConfiguration(final Configuration freemarkerMailConfiguration) {
        this.freemarkerMailConfiguration = freemarkerMailConfiguration;
    }

    public void setSuppressMail(final boolean suppressMail) {
        this.suppressMail = suppressMail;
    }

    @Override
    public void sendTextMail(final MailMetaData mailMetaData, final String text) {
        if (suppressMail) {
            LOGGER.info(
                    "Message suppress switch is on in dcma-mail.properties file. Error mail notfication cann't be send");
            return;
        }
        setMailProperties();
        final SimpleMailMessage mailMessage = new SimpleMailMessage();
        if (mailMetaData.getFromAddress() != null) {
            mailMessage.setFrom(EphesoftStringUtil.concatenate(mailMetaData.getFromName(),
                    MailConstants.LESS_SYMBOL, mailMetaData.getFromAddress(), MailConstants.GREATER_SYMBOL));
        }
        if (null != mailMetaData.getSubject()) {
            mailMessage.setSubject(mailMetaData.getSubject());
        }
        if (mailMetaData.getCcAddresses() != null && mailMetaData.getCcAddresses().size() > 0) {
            mailMessage.setCc((String[]) mailMetaData.getCcAddresses()
                    .toArray(new String[mailMetaData.getCcAddresses().size()]));
        }
        if (mailMetaData.getBccAddresses() != null && mailMetaData.getBccAddresses().size() > 0) {
            mailMessage.setBcc((String[]) mailMetaData.getBccAddresses()
                    .toArray(new String[mailMetaData.getBccAddresses().size()]));
        }
        if (mailMetaData.getToAddresses() != null && mailMetaData.getToAddresses().size() > 0) {
            mailMessage.setTo((String[]) mailMetaData.getToAddresses()
                    .toArray(new String[mailMetaData.getToAddresses().size()]));
        }
        mailMessage.setText(text);
        try {
            mailSender.send(mailMessage);
        } catch (MailException mailException) {
            LOGGER.error("Eror while sending mail to configured mail account", mailException);
            throw new SendMailException(
                    EphesoftStringUtil.concatenate("Error sending mail: ", mailMetaData.toString()), mailException);
        }
        LOGGER.info("mail sent successfully");
    }

    /**
     * API to Set socket factory class according to the SSL or NON-SSL option selected by user.
     */
    private void setMailProperties() {
        Properties mailProperties = mailSender.getJavaMailProperties();
        String sslEnabled = (String) mailProperties.get(MailConstants.MAIL_SMTP_SSL_PROPERTY);
        if (!EphesoftStringUtil.isNullOrEmpty(sslEnabled) && sslEnabled.equalsIgnoreCase(MailConstants.TRUE)) {
            mailProperties.setProperty(MailConstants.MAIL_SOCKET_PROPERTY, MailConstants.MAIL_SOCKET_CLASS);
        }
    }

    @Override
    public void sendMailWithPreviousMailContent(final MailMetaData mailMetaData, final String text,
            final Message previousMailMessage) {
        LOGGER.debug("Sending mail with content from previous mail(MailServiceImpl)");
        if (suppressMail) {
            return;
        }
        setMailProperties();
        MimeMessagePreparator messagePreparator = new MimeMessagePreparator() {

            public void prepare(MimeMessage mimeMessage) throws Exception {

                if (null != mailMetaData.getCcAddresses() && mailMetaData.getCcAddresses().size() > 0) {
                    setAddressToMessage(RecipientType.CC, mimeMessage, mailMetaData.getCcAddresses());
                }
                if (null != mailMetaData.getBccAddresses() && mailMetaData.getBccAddresses().size() > 0) {
                    setAddressToMessage(RecipientType.BCC, mimeMessage, mailMetaData.getBccAddresses());
                }
                if (null != mailMetaData.getToAddresses() && mailMetaData.getToAddresses().size() > 0) {
                    setAddressToMessage(RecipientType.TO, mimeMessage, mailMetaData.getToAddresses());
                }

                if (null != mailMetaData.getFromAddress()) {
                    mimeMessage.setFrom(new InternetAddress(new StringBuilder().append(mailMetaData.getFromName())
                            .append(MailConstants.LESS_SYMBOL).append(mailMetaData.getFromAddress())
                            .append(MailConstants.GREATER_SYMBOL).toString()));
                }

                if (null != mailMetaData.getSubject() && null != text) {
                    mimeMessage.setSubject(mailMetaData.getSubject());
                }

                if (null != text) {
                    mimeMessage.setText(text);
                }

                // Create your new message part
                BodyPart messageBodyPart = new MimeBodyPart();
                messageBodyPart.setText(EphesoftStringUtil.concatenate(text, ORIGINAL_MAIL_MESSAGE));

                // Create a multi-part to combine the parts
                Multipart multipart = new MimeMultipart();
                multipart.addBodyPart(messageBodyPart);

                // Create and fill part for the forwarded content
                messageBodyPart = new MimeBodyPart();
                messageBodyPart.setDataHandler(previousMailMessage.getDataHandler());

                // Add part to multi part
                multipart.addBodyPart(messageBodyPart);

                // Associate multi-part with message
                mimeMessage.setContent(multipart);

            }
        };
        try {
            mailSender.send(messagePreparator);
        } catch (MailException mailException) {
            LOGGER.error("Error while sending mail to configured mail account", mailException);
            throw new SendMailException(
                    EphesoftStringUtil.concatenate("Error sending mail: ", mailMetaData.toString()), mailException);
        }
        LOGGER.info("mail sent successfully");
    }

    /**
     * To set receiptent's mail ids in message to be sent.
     * 
     * @param receiptentType {@link RecipientType}
     * @param mimeMessage {@link MimeMessage}
     * @param addressList {@link List}
     */
    private void setAddressToMessage(RecipientType receiptentType, MimeMessage mimeMessage,
            List<String> addressList) {
        try {
            for (String address : addressList) {
                mimeMessage.addRecipients(receiptentType, address);
            }
        } catch (MessagingException messagingException) {
            throw new SendMailException(new StringBuilder()
                    .append("Error while setting address. PLease verify email addresses").toString(),
                    messagingException);
        }

    }

    @Override
    public void sendTextMailWithClasspathTemplate(final MailMetaData mailMetaData, final String templateLocation,
            final MailContentModel model) {
        LOGGER.debug("Inside sendTextMailWithClasspathTemplate");
        if (null != mailMetaData && null != templateLocation && null != model) {
            model.add(MailConstants.MAIL_META, mailMetaData);
            try {
                LOGGER.info("Sending mail from: " + mailMetaData.getFromAddress());
                final String result = FreeMarkerTemplateUtils.processTemplateIntoString(
                        freemarkerMailConfiguration.getTemplate(templateLocation), model.getModel());
                LOGGER.info("Resultant mail is: " + result);
                sendTextMail(mailMetaData, result);
            } catch (Exception exception) {
                LOGGER.error("Error while sending mail(Workflow error): ", exception);
                throw new SendMailException(
                        EphesoftStringUtil.concatenate("Error sending mail: ", mailMetaData.toString()), exception);
            }
        } else {
            LOGGER.error("Some of the input values are null. \n 1) MailMetaData  2) TemplateLocation 3) model");
        }
    }

    @Override
    public void sendTextMailWithClasspathTemplate(final MailMetaData mailMetaData, final String templateLocation,
            final MailContentModel model, Message previousMailMessage) {
        LOGGER.debug("Inside sendTextMailWithClasspathTemplate");
        if (null != mailMetaData && null != templateLocation && null != model) {
            model.add(MailConstants.MAIL_META, mailMetaData);
            try {
                LOGGER.info(EphesoftStringUtil.concatenate("Sending mail from: ", mailMetaData.getFromAddress(),
                        " \n Template Location:  ", templateLocation));
                final String result = FreeMarkerTemplateUtils.processTemplateIntoString(
                        freemarkerMailConfiguration.getTemplate(templateLocation), model.getModel());
                LOGGER.info(EphesoftStringUtil.concatenate("Resultant mail is (without previous mail content): ",
                        result));
                sendMailWithPreviousMailContent(mailMetaData, result, previousMailMessage);
            } catch (Exception exception) {
                LOGGER.error("Error while sending mail(Mail processing error): ", exception);
                throw new SendMailException(
                        EphesoftStringUtil.concatenate("Error sending mail: ", mailMetaData.toString()), exception);
            }
        } else {
            LOGGER.error("Some of the input values are null. \n 1) MailMetaData  2) TemplateLocation 3) model");
        }
    }

    @Override
    public void mailOnWorkflowError(BatchInstance batchInstance, Exception exception, String subject,
            String mailTemplatePath, String errorPlugin) throws DCMAApplicationException {
        LOGGER.trace("Creating  mailMetaData in Mail service impl");
        if (null != batchInstance && null != exception) {
            MailMetaData metaData = new MailMetaData();
            metaData.setFromAddress(this.fromMail);
            metaData.setFromName(this.fromMail);
            metaData.setSubject(subject);
            metaData.setToAddresses(new ArrayList<String>(StringUtils.commaDelimitedListToSet(toMail)));
            MailContentModel model = new MailContentModel();
            model.add(MailConstants.WORKFLOW, batchInstance.getBatchClass().getName());
            model.add(MailConstants.BATCH_INSTANCE, batchInstance.getIdentifier());
            model.add(MailConstants.BATCH_NAME, batchInstance.getBatchName());
            String exceptionMessage = exception.getMessage();
            if (null == exceptionMessage) {
                exceptionMessage = ICommonConstants.EMPTY_STRING;
            }
            model.add(MailConstants.ERROR_MESSAGE, exceptionMessage);
            model.add(MailConstants.ERROR_LOG, ExceptionUtils.getFullStackTrace(exception));
            model.add(MailConstants.ERROR_PLUGIN, errorPlugin);
            try {
                sendTextMailWithClasspathTemplate(metaData, mailTemplatePath, model);
            } catch (final SendMailException sendMailException) {
                LOGGER.error("Error encountered while sending mail.", sendMailException);
                throw new DCMAApplicationException("Error encountered while sending mail.", sendMailException);
            }
        } else {
            LOGGER.error(
                    "Either or both batchInstance or exception object is null. Error notification mail cann't be sent.");
        }
        LOGGER.trace("Exiting mail send on error for workflow in Mail service impl");
    }

    @Override
    public void mailOnError(final String subject, final Message previousMailMessage, final String batchClassName,
            final String userName, final String mailTemplatePath) throws DCMAApplicationException {
        LOGGER.debug("Creating  mailMetaData odr mail or error.");
        if (null != subject && null != batchClassName && null != userName && null != previousMailMessage) {
            final MailMetaData metaData = new MailMetaData();
            metaData.setFromAddress(fromMail);
            metaData.setFromName(fromMail);
            metaData.setSubject(subject);
            metaData.setToAddresses(new ArrayList<String>(StringUtils.commaDelimitedListToSet(toMail)));
            final MailContentModel model = new MailContentModel();
            model.add(MailConstants.BATCH_CLASS, batchClassName);
            model.add(MailConstants.USER_ID, userName);
            try {
                String ccString = Arrays.toString(previousMailMessage.getHeader(MailConstants.CC))
                        .replace(MailConstants.OPENING_BRACKET, MailConstants.SPACE)
                        .replace(MailConstants.CLOSING_BRACKET, MailConstants.EMPTY_STRING);
                String toString = Arrays.toString(previousMailMessage.getHeader(MailConstants.TO))
                        .replace(MailConstants.OPENING_BRACKET, MailConstants.SPACE)
                        .replace(MailConstants.CLOSING_BRACKET, MailConstants.EMPTY_STRING);

                // below date format will be used to format date string received
                // from mail header. Mail header can provide a lot more
                // info.
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(MailConstants.DATE_FORMAT);
                model.add(MailConstants.SUBJECT, previousMailMessage.getSubject());
                model.add(MailConstants.FROM,
                        Arrays.toString(previousMailMessage.getHeader(MailConstants.FROM))
                                .replace(MailConstants.OPENING_BRACKET, MailConstants.SPACE)
                                .replace(MailConstants.CLOSING_BRACKET, ""));
                model.add(MailConstants.TO,
                        toString.equalsIgnoreCase(MailConstants.NULL_STRING) ? MailConstants.EMPTY_STRING
                                : toString);
                model.add(MailConstants.CC,
                        ccString.equalsIgnoreCase(MailConstants.NULL_STRING) ? MailConstants.EMPTY_STRING
                                : ccString);
                model.add(MailConstants.RECEIVED_DATE,
                        simpleDateFormat
                                .parseObject(previousMailMessage.getHeader(MailConstants.DATE_STRING)[0].toString())
                                .toString());
            } catch (javax.mail.MessagingException mailException) {
                LOGGER.error("Error encountered while extarcting info from previos mail object", mailException);
                throw new DCMAApplicationException(
                        "Error encountered while extarcting infor from previos mail object", mailException);
            } catch (java.text.ParseException parseException) {
                LOGGER.error(
                        "Error encountered while parsing date extracted from mail header of previos mail object",
                        parseException);
                throw new DCMAApplicationException(
                        "Error encountered while parsing received date from previos mail object", parseException);
            }
            LOGGER.debug(
                    EphesoftStringUtil.concatenate("Batch Class Name: ", batchClassName, "  UserName: ", userName));
            sendTextMailWithClasspathTemplate(metaData, mailTemplatePath, model, previousMailMessage);
        } else {
            LOGGER.error(
                    "Either or all of the following values are null. Error notification mail cann't be sent. \n Subject,BatchClassName, UserName");
        }
    }

}