de.hybris.platform.acceleratorservices.email.impl.DefaultEmailService.java Source code

Java tutorial

Introduction

Here is the source code for de.hybris.platform.acceleratorservices.email.impl.DefaultEmailService.java

Source

/*
 * [y] hybris Platform
 *
 * Copyright (c) 2000-2014 hybris AG
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of hybris
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with hybris.
 *
 *  
 */
package de.hybris.platform.acceleratorservices.email.impl;

import de.hybris.platform.acceleratorservices.email.EmailService;
import de.hybris.platform.acceleratorservices.email.strategy.EmailAddressFetchStrategy;
import de.hybris.platform.acceleratorservices.model.email.EmailAddressModel;
import de.hybris.platform.acceleratorservices.model.email.EmailAttachmentModel;
import de.hybris.platform.acceleratorservices.model.email.EmailMessageModel;
import de.hybris.platform.catalog.CatalogService;
import de.hybris.platform.catalog.CatalogVersionService;
import de.hybris.platform.catalog.model.CatalogVersionModel;
import de.hybris.platform.cms2.model.contents.ContentCatalogModel;
import de.hybris.platform.core.model.media.MediaFolderModel;
import de.hybris.platform.core.model.media.MediaModel;
import de.hybris.platform.servicelayer.config.ConfigurationService;
import de.hybris.platform.servicelayer.internal.service.AbstractBusinessService;
import de.hybris.platform.servicelayer.media.MediaService;
import de.hybris.platform.servicelayer.media.NoDataAvailableException;
import de.hybris.platform.util.mail.MailUtils;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.activation.DataSource;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.util.ByteArrayDataSource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;

/**
 * Service to create and send emails.
 */
public class DefaultEmailService extends AbstractBusinessService implements EmailService {
    private static final Logger LOG = Logger.getLogger(DefaultEmailService.class);

    public static final String EMAILSERVICE_SEND_ENABLED_CONFIG_KEY = "emailservice.send.enabled";
    public static final int EMAIL_BODY_MAX_LENGTH = 4000;
    public static final String EMAIL_BODY_ENCODING = "UTF-8";
    public static final String EMAIL_BODY_MIME_TYPE = "text/html";//"text/plain";

    private String emailAttachmentsMediaFolderName;
    private String emailBodyMediaFolderName;
    private MediaService mediaService;
    private ConfigurationService configurationService;
    private CatalogVersionService catalogVersionService;
    private CatalogService catalogService;

    private EmailAddressFetchStrategy emailAddressFetchStrategy;

    @Override
    public EmailAddressModel getOrCreateEmailAddressForEmail(final String emailAddress, final String displayName) {
        return getEmailAddressFetchStrategy().fetch(emailAddress, displayName);
    }

    @Override
    public EmailAttachmentModel createEmailAttachment(final DataInputStream masterDataStream, final String filename,
            final String mimeType) {
        final EmailAttachmentModel attachment = getModelService().create(EmailAttachmentModel.class);
        attachment.setCode(filename);
        attachment.setMime(mimeType);
        attachment.setRealFileName(filename);
        attachment.setCatalogVersion(getCatalogVersion());
        getModelService().save(attachment);

        getMediaService().setStreamForMedia(attachment, masterDataStream, filename, mimeType,
                getEmailAttachmentsMediaFolder());
        return attachment;
    }

    protected MediaFolderModel getEmailAttachmentsMediaFolder() {
        return getMediaService().getFolder(getEmailAttachmentsMediaFolderName());
    }

    protected MediaFolderModel getEmailBodyMediaFolder() {
        return getMediaService().getFolder(getEmailBodyMediaFolderName());
    }

    @Override
    public EmailMessageModel createEmailMessage(final List<EmailAddressModel> toAddresses,
            final List<EmailAddressModel> ccAddresses, final List<EmailAddressModel> bccAddresses,
            final EmailAddressModel fromAddress, final String replyToAddress, final String subject,
            final String body, final List<EmailAttachmentModel> attachments) {
        // Do all validation now before creating the message
        if (toAddresses == null || toAddresses.isEmpty()) {
            throw new IllegalArgumentException("toAddresses must not be empty");
        }
        if (fromAddress == null) {
            throw new IllegalArgumentException("fromAddress must not be null");
        }
        if (subject == null || subject.isEmpty()) {
            throw new IllegalArgumentException("subject must not be empty");
        }
        if (body == null || body.isEmpty()) {

            throw new IllegalArgumentException("body must not be empty");
        }
        validateEmailAddress(replyToAddress, "replyToAddress");

        final EmailMessageModel emailMessageModel = getModelService().create(EmailMessageModel.class);
        emailMessageModel.setToAddresses(toAddresses);
        emailMessageModel.setCcAddresses(ccAddresses);
        emailMessageModel.setBccAddresses(bccAddresses);
        emailMessageModel.setFromAddress(fromAddress);
        emailMessageModel.setReplyToAddress((replyToAddress != null && !replyToAddress.isEmpty()) ? replyToAddress
                : fromAddress.getEmailAddress());
        emailMessageModel.setSubject(subject);
        emailMessageModel.setAttachments(attachments);
        if (body.length() < EMAIL_BODY_MAX_LENGTH) {
            emailMessageModel.setBody(body);
            getModelService().save(emailMessageModel);
        } else {
            getModelService().save(emailMessageModel);
            final MediaModel bodyMedia = createBodyMedia("bodyMedia-" + emailMessageModel.getPk(), body);
            emailMessageModel.setBodyMedia(bodyMedia);
            getModelService().save(emailMessageModel);
        }

        return emailMessageModel;
    }

    /**
     * Method creates MediaModel object for storing email body
     * 
     * @param bodyMediaName
     *           - name for created object
     * @param body
     *           - content of email body
     * @return created MediaModel object
     */
    protected MediaModel createBodyMedia(final String bodyMediaName, final String body) {
        final MediaModel bodyMedia = getModelService().create(MediaModel.class);
        bodyMedia.setCatalogVersion(getCatalogVersion());
        bodyMedia.setCode(bodyMediaName);
        bodyMedia.setMime(EMAIL_BODY_MIME_TYPE);
        bodyMedia.setRealFileName(bodyMediaName);
        getModelService().save(bodyMedia);

        final MediaFolderModel mediaFolderModel = getEmailBodyMediaFolder();
        InputStream dataStream = null;
        try {
            try {
                dataStream = new ByteArrayInputStream(body.getBytes(EMAIL_BODY_ENCODING));
            } catch (final UnsupportedEncodingException e) {
                dataStream = new ByteArrayInputStream(body.getBytes());
                LOG.warn("emailBody - UnsupportedEncodingException", e);
            }
            mediaService.setStreamForMedia(bodyMedia, dataStream, bodyMediaName, EMAIL_BODY_MIME_TYPE,
                    mediaFolderModel);
        } finally {
            try {
                if (dataStream != null) {
                    dataStream.close();
                }
            } catch (final IOException e) {
                // ignored
            }
        }
        return bodyMedia;
    }

    protected CatalogVersionModel getCatalogVersion() {
        CatalogVersionModel catalogVersion = getCatalogService().getDefaultCatalog() == null ? null
                : getCatalogService().getDefaultCatalog().getActiveCatalogVersion();
        if (catalogVersion == null) {
            final Collection<CatalogVersionModel> catalogs = getCatalogVersionService().getSessionCatalogVersions();
            for (final CatalogVersionModel cvm : catalogs) {
                if (cvm.getCatalog() instanceof ContentCatalogModel) {
                    catalogVersion = cvm;
                    break;
                }
            }
        }

        return catalogVersion;
    }

    protected void validateEmailAddress(final String address, final String type) {
        try {
            if (address != null && !address.isEmpty()) {
                MailUtils.validateEmailAddress(address, type);
            }
        } catch (final EmailException ex) {
            throw new IllegalArgumentException(type, ex);
        }
    }

    @Override
    public boolean send(final EmailMessageModel message) {
        if (message == null) {
            throw new IllegalArgumentException("message must not be null");
        }

        final boolean sendEnabled = getConfigurationService().getConfiguration()
                .getBoolean(EMAILSERVICE_SEND_ENABLED_CONFIG_KEY, true);
        if (sendEnabled) {
            try {
                final HtmlEmail email = getPerConfiguredEmail();
                email.setCharset("UTF-8");

                final List<EmailAddressModel> toAddresses = message.getToAddresses();
                if (CollectionUtils.isNotEmpty(toAddresses)) {
                    email.setTo(getAddresses(toAddresses));
                } else {
                    throw new IllegalArgumentException("message has no To addresses");
                }

                final List<EmailAddressModel> ccAddresses = message.getCcAddresses();
                if (ccAddresses != null && !ccAddresses.isEmpty()) {
                    email.setCc(getAddresses(ccAddresses));
                }

                final List<EmailAddressModel> bccAddresses = message.getBccAddresses();
                if (bccAddresses != null && !bccAddresses.isEmpty()) {
                    email.setBcc(getAddresses(bccAddresses));
                }

                final EmailAddressModel fromAddress = message.getFromAddress();
                email.setFrom(fromAddress.getEmailAddress(), nullifyEmpty(fromAddress.getDisplayName()));

                // Add the reply to if specified
                final String replyToAddress = message.getReplyToAddress();
                if (replyToAddress != null && !replyToAddress.isEmpty()) {
                    email.setReplyTo(Collections.singletonList(createInternetAddress(replyToAddress, null)));
                }

                email.setSubject(message.getSubject());
                email.setHtmlMsg(getBody(message));

                // To support plain text parts use email.setTextMsg()

                final List<EmailAttachmentModel> attachments = message.getAttachments();
                if (attachments != null && !attachments.isEmpty()) {
                    for (final EmailAttachmentModel attachment : attachments) {
                        try {
                            final DataSource dataSource = new ByteArrayDataSource(
                                    getMediaService().getDataFromMedia(attachment), attachment.getMime());
                            email.attach(dataSource, attachment.getRealFileName(), attachment.getAltText());
                        } catch (final EmailException ex) {
                            LOG.error("Failed to load attachment data into data source [" + attachment + "]", ex);
                            return false;
                        }
                    }
                }

                // Important to log all emails sent out
                LOG.info("Sending Email [" + message.getPk() + "] To [" + convertToStrings(toAddresses) + "] From ["
                        + fromAddress.getEmailAddress() + "] Subject [" + email.getSubject() + "]");

                // Send the email and capture the message ID
                final String messageID = email.send();

                message.setSent(true);
                message.setSentMessageID(messageID);
                message.setSentDate(new Date());
                getModelService().save(message);

                return true;
            } catch (final EmailException e) {
                LOG.warn("Could not send e-mail pk [" + message.getPk() + "] subject [" + message.getSubject()
                        + "] cause: " + e.getMessage());
                if (LOG.isDebugEnabled()) {
                    LOG.debug(e);
                }
            }
        } else {
            LOG.warn("Could not send e-mail pk [" + message.getPk() + "] subject [" + message.getSubject() + "]");
            LOG.info("Email sending has been disabled. Check the config property 'emailservice.send.enabled'");
            return true;
        }

        return false;
    }

    protected HtmlEmail getPerConfiguredEmail() throws EmailException {
        return (HtmlEmail) MailUtils.getPreConfiguredEmail();
    }

    /**
     * Method checks which attribute is storing email body (bodyMedia or body) and return its content as string
     * 
     * @param message
     *           - email message object
     * @return email body
     */
    protected String getBody(final EmailMessageModel message) {
        if (message.getBodyMedia() != null) {
            final MediaModel media = message.getBodyMedia();
            String body;
            try {
                body = new String(mediaService.getDataFromMedia(media), EMAIL_BODY_ENCODING);
            } catch (final NoDataAvailableException e) {
                return message.getBody();
            } catch (final UnsupportedEncodingException e) {
                body = new String(mediaService.getDataFromMedia(media));
            }
            return body;
        } else {
            return message.getBody();
        }
    }

    protected String nullifyEmpty(final String str) {
        if (str != null && str.isEmpty()) {
            return null;
        }
        return str;
    }

    protected Collection<InternetAddress> getAddresses(final List<EmailAddressModel> emailAddresses) {
        final Collection<InternetAddress> internetAddresses = new ArrayList<InternetAddress>();

        for (final EmailAddressModel emailAddress : emailAddresses) {
            try {
                internetAddresses
                        .add(createInternetAddress(emailAddress.getEmailAddress(), emailAddress.getDisplayName()));
            } catch (final EmailException e) {
                LOG.warn("Failed to lookup to address [" + emailAddress + "]", e);
            }
        }
        return internetAddresses;
    }

    protected InternetAddress createInternetAddress(final String emailAddress, final String displayName)
            throws EmailException {
        try {
            final InternetAddress address = new InternetAddress(emailAddress);
            address.setPersonal(StringUtils.isNotBlank(displayName) ? displayName : emailAddress);
            address.validate();
            return address;
        } catch (final AddressException e) {
            throw new EmailException(e);
        } catch (final UnsupportedEncodingException e) {
            throw new EmailException(e);
        }
    }

    protected List<String> convertToStrings(final List<EmailAddressModel> addresses) {
        final List<String> strings = new ArrayList<String>();
        if (addresses != null && !addresses.isEmpty()) {
            for (final EmailAddressModel item : addresses) {
                strings.add(item.getEmailAddress());
            }
        }
        return strings;
    }

    public EmailAddressFetchStrategy getEmailAddressFetchStrategy() {
        return emailAddressFetchStrategy;
    }

    @Required
    public void setEmailAddressFetchStrategy(final EmailAddressFetchStrategy emailAddressFetchStrategy) {
        this.emailAddressFetchStrategy = emailAddressFetchStrategy;
    }

    protected String getEmailAttachmentsMediaFolderName() {
        return emailAttachmentsMediaFolderName;
    }

    @Required
    public void setEmailAttachmentsMediaFolderName(final String emailAttachmentsMediaFolderName) {
        this.emailAttachmentsMediaFolderName = emailAttachmentsMediaFolderName;
    }

    protected String getEmailBodyMediaFolderName() {
        return emailBodyMediaFolderName;
    }

    @Required
    public void setEmailBodyMediaFolderName(final String emailBodyMediaFolderName) {
        this.emailBodyMediaFolderName = emailBodyMediaFolderName;
    }

    protected MediaService getMediaService() {
        return mediaService;
    }

    @Required
    public void setMediaService(final MediaService mediaService) {
        this.mediaService = mediaService;
    }

    protected ConfigurationService getConfigurationService() {
        return configurationService;
    }

    @Required
    public void setConfigurationService(final ConfigurationService configurationService) {
        this.configurationService = configurationService;
    }

    protected CatalogVersionService getCatalogVersionService() {
        return catalogVersionService;
    }

    @Required
    public void setCatalogVersionService(final CatalogVersionService catalogVersionService) {
        this.catalogVersionService = catalogVersionService;
    }

    protected CatalogService getCatalogService() {
        return catalogService;
    }

    @Required
    public void setCatalogService(final CatalogService catalogService) {
        this.catalogService = catalogService;
    }
}