Package com.cedarsolutions.util.gae

Source Code of com.cedarsolutions.util.gae.GaeEmailUtils

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
*              C E D A R
*          S O L U T I O N S       "Software done right."
*           S O F T W A R E
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (c) 2013 Kenneth J. Pronovici.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Apache License, Version 2.0.
* See LICENSE for more information about the licensing terms.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Author   : Kenneth J. Pronovici <pronovic@ieee.org>
* Language : Java 6
* Project  : Common Java Functionality
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package com.cedarsolutions.util.gae;

import static com.cedarsolutions.shared.domain.email.EmailFormat.PLAINTEXT;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
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 com.cedarsolutions.exception.CedarRuntimeException;
import com.cedarsolutions.shared.domain.email.EmailAddress;
import com.cedarsolutions.shared.domain.email.EmailMessage;
import com.cedarsolutions.util.StringUtils;

/**
* General email utilities.
*
* <p>
* These utilities have been tested with the Google App Engine SMTP server,
* and not any other SMTP servers.  As a result, I can't promise that the
* multipart functionality will work properly outside of GAE.  (Based on
* what I have read, multipart is one of those places where behavior seems
* to vary a bit by back-end.)
* </p>
*
* <p>
* Normally, I would impelement utility code like this as static methods.
* However, it's difficult to mock static method calls, and the methods below
* are complicated enough that I want that option.  Instead, an instance of
* this class should be injected into any other class that needs this
* functionality.  It's safe to treat that instance as a singleton, but you
* don't have to.
* </p>
*
* @author Kenneth J. Pronovici <pronovic@ieee.org>
*/
public class GaeEmailUtils {

    /** Charset that will be used. */
    public static final String CHARSET = "iso-8859-1";

    /**
     * Send an email message via the Google App Engine API.
     * @param message Message to send
     * @throws CedarRuntimeException If the email cannot be sent.
     */
    public void sendMessage(Message message) {
        try {
            // This method can't really be unit tested, because we can't mock Transport.
            Transport.send(message);
        } catch (Exception e) {
            throw new CedarRuntimeException("Failed to send message: " + e.getMessage(), e);
        }
    }

    /**
     * Create a JavaMail message based on an EmailMessage.
     * @param email  EmailMessage to use as source
     * @return JavaMail message generated based on input EmailMessage.
     */
    public Message createMessage(EmailMessage email) {
        InternetAddress sender = createInternetAddress(email.getSender());
        InternetAddress replyTo = createInternetAddress(email.getReplyTo());

        List<InternetAddress> recipients = new ArrayList<InternetAddress>();
        for (EmailAddress address : email.getRecipients()) {
            InternetAddress recipient = createInternetAddress(address);
            recipients.add(recipient);
        }

        if (email.getFormat() == PLAINTEXT) {
            return createPlaintextMessage(sender, recipients, replyTo, email.getSubject(), email.getPlaintext());
        } else {
            return createMultipartMessage(sender, recipients, replyTo, email.getSubject(), email.getPlaintext(), email.getHtml());
        }
    }

    /**
     * Create an InternetAddress based on an EmailAddress.
     * @return InternetAddress for the passed-in arguments.
     * @throws CedarRuntimeException  If there's a problem creating the address.
     */
    public InternetAddress createInternetAddress(EmailAddress address) {
        try {
            return createInternetAddress(address.getAddress(), address.getName());
        } catch (NullPointerException e) {
            throw new CedarRuntimeException("Unable to create internet address: " + e.getMessage(), e);
        }
    }

    /**
     * Create an InternetAddress.
     * @param emailAddress  Email address
     * @param fullName      Full name
     * @return InternetAddress for the passed-in arguments.
     * @throws CedarRuntimeException  If there's a problem creating the address.
     */
    public InternetAddress createInternetAddress(String emailAddress, String fullName) {
        try {
            if (!StringUtils.isEmpty(emailAddress) && !StringUtils.isEmpty(fullName)) {
                return new InternetAddress(emailAddress, fullName);
            } else if (!StringUtils.isEmpty(emailAddress)) {
                return new InternetAddress(emailAddress);
            } else {
                throw new CedarRuntimeException("Must provide email address; full name is optional.");
            }
        } catch (Exception e) {
            throw new CedarRuntimeException("Unable to create internet address: " + e.getMessage(), e);
        }
    }

    /**
     * Get the plaintext part of an email message.
     * @param message   Message to introspect (must have been originally generated by this class)
     * @return Text part of the message, or null if there is no text part.
     */
    public String getTextPart(Message message) {
        try {
            if (message != null) {
                if (message.getContent() instanceof String) {
                    if ("text/plain".equals(message.getContentType())) {
                        return (String) message.getContent();
                    }
                } else if (message.getContent() instanceof Multipart) {
                    Multipart multipart = (Multipart) message.getContent();
                    if (multipart.getCount() == 2) {
                        MimeBodyPart textPart = (MimeBodyPart) multipart.getBodyPart(0);
                        if (textPart.getContent() instanceof String) {
                            if (StringUtils.startsWith(textPart.getContentType(), "text/plain")) {
                                return (String) textPart.getContent();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) { }

        return null;
    }

    /**
     * Get the HTML part of an email message.
     * @param message   Message to introspect (must have been originally generated by this class)
     * @return HTML part of the message, or null if there is no HTML part.
     */
    public String getHtmlPart(Message message) {
        try {
            if (message != null) {
                if (message.getContent() instanceof Multipart) {
                    Multipart multipart = (Multipart) message.getContent();
                    if (multipart.getCount() == 2) {
                        MimeBodyPart htmlPart = (MimeBodyPart) multipart.getBodyPart(1);
                        if (htmlPart.getContent() instanceof String) {
                            if (StringUtils.startsWith(htmlPart.getContentType(), "text/html")) {
                                return (String) htmlPart.getContent();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) { }

        return null;
    }

    /**
     * Create a plaintext email message.
     * @param sender     Message sender
     * @param recipients Message recipients
     * @param replyTo    Reply to email address, or null
     * @param subject    Message subject
     * @param plaintext  Plaintext message body
     * @return Plaintext message suitable for passing to sendMessage().
     * @throws CedarRuntimeException If the email cannot be sent.
     */
    public Message createPlaintextMessage(InternetAddress sender,
                                          List<InternetAddress> recipients,
                                          InternetAddress replyTo,
                                          String subject, String plaintext) {
        try {
            if (StringUtils.isEmpty(plaintext)) {
                throw new CedarRuntimeException("Must provide plaintext body.");
            }

            Message message = createBasicMessage(sender, recipients, replyTo, subject);
            message.setText(plaintext);
            return message;
        } catch (CedarRuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new CedarRuntimeException("Failed to create message: " + e.getMessage(), e);
        }
    }

    /**
     * Create a multipart/alternative email message with both plaintext and HTML parts.
     * @param sender     Message sender
     * @param recipients Message recipients
     * @param replyTo    Reply to email address, or null
     * @param subject    Message subject
     * @param plaintext  Plaintext message body
     * @param html       HTML message body, or null
     * @see <a href="http://www.thatsjava.com/java-enterprise/29158/">thatsjava.com</a>
     * @return Multipart/alternative message suitable for passing to sendMessage().
     * @throws CedarRuntimeException If the email cannot be sent.
     */
    public Message createMultipartMessage(InternetAddress sender,
                                          List<InternetAddress> recipients,
                                          InternetAddress replyTo,
                                          String subject, String plaintext, String html) {
        try {
            // Ick!  This is incredibly ugly.  I don't quite understand why there
            // is not an easier way to generate a multipart/alternative message.
            // However, this seems to work, so we'll go with it.

            if (StringUtils.isEmpty(plaintext) || StringUtils.isEmpty(html)) {
                throw new CedarRuntimeException("Must provide HTML and plaintext parts.");
            }

            MimeBodyPart plaintextPart = new MimeBodyPart();
            plaintextPart.setText(plaintext);
            plaintextPart.addHeaderLine("Content-Type: text/plain; charset=\"" + CHARSET + "\"");
            plaintextPart.addHeaderLine("Content-Transfer-Encoding: quoted-printable");

            MimeBodyPart htmlPart = new MimeBodyPart();
            htmlPart.setText(html);
            htmlPart.addHeaderLine("Content-Type: text/html; charset=\"" + CHARSET + "\"");
            htmlPart.addHeaderLine("Content-Transfer-Encoding: quoted-printable");

            Multipart content = new MimeMultipart("alternative");
            content.addBodyPart(plaintextPart);
            content.addBodyPart(htmlPart);

            Message message = createBasicMessage(sender, recipients, replyTo, subject);
            message.setContent(content);
            return message;
        } catch (CedarRuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new CedarRuntimeException("Failed to create message: " + e.getMessage(), e);
        }
    }

    /**
     * Create a basic email message, including components shared with text and multipart formats.
     * @param sender     Message sender
     * @param recipients Message recipients
     * @param replyTo    Reply to email address, or null
     * @param subject    Message subject
     * @return Basic message that can be added to for other scenarios.
     * @throws MessagingException If there is an underlying JavaMail problem.
     * @throws CedarRuntimeException If arguments are invalid.
     */
    private Message createBasicMessage(InternetAddress sender,
                                       List<InternetAddress> recipients,
                                       InternetAddress replyTo,
                                       String subject) throws MessagingException {

        if (sender == null) {
            throw new CedarRuntimeException("Must provide sender.");
        }

        if (recipients == null || recipients.isEmpty()) {
            throw new CedarRuntimeException("Must provide recipients.");
        }

        if (StringUtils.isEmpty(subject)) {
            throw new CedarRuntimeException("Must provide subject.");
        }

        Session session = Session.getDefaultInstance(new Properties(), null);
        Message message = new MimeMessage(session);
        message.setFrom(sender);
        message.setSubject(subject);

        for (InternetAddress recipient : recipients) {
            message.addRecipient(Message.RecipientType.TO, recipient);
        }

        if (replyTo != null) {
            message.setReplyTo(new Address[] { replyTo, });
        }

        return message;
    }

}
TOP

Related Classes of com.cedarsolutions.util.gae.GaeEmailUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.