Package cn.bran.play

Source Code of cn.bran.play.Mail$SMTPAuthenticator

package cn.bran.play;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;

import play.Logger;
import play.Play;
import cn.bran.play.exceptions.MailException;

/**
* Mail utils
*/
public class Mail {

  public static Session session;
  public static boolean asynchronousSend = true;

  /**
   * Send an email
   */
  public static Future<Boolean> send(Email email) {
    try {
      email = buildMessage(email);

      String string = getConfig("mail.smtp.host"); // has to use this since mail.smtp is a tree in play2
      if (string != null)
        if (string.equals("mock") && Play.isDev()) {
          Mock.send(email);
          return new Future<Boolean>() {

            public boolean cancel(boolean mayInterruptIfRunning) {
              return false;
            }

            public boolean isCancelled() {
              return false;
            }

            public boolean isDone() {
              return true;
            }

            public Boolean get() throws InterruptedException,
                ExecutionException {
              return true;
            }

            public Boolean get(long timeout, TimeUnit unit)
                throws InterruptedException,
                ExecutionException, TimeoutException {
              return true;
            }
          };
        }

      email.setMailSession(getSession());
      return sendMessage(email);
    } catch (EmailException ex) {
      throw new MailException("Cannot send email", ex);
    }
  }

  /**
     *
     */
  public static Email buildMessage(Email email) throws EmailException {

    String from = Play.application().configuration()
        .getString("mail.smtp.from");

    if (email.getFromAddress() == null && !StringUtils.isEmpty(from)) {
      email.setFrom(from);
    } else if (email.getFromAddress() == null) {
      throw new MailException("Please define a 'from' email address",
          new NullPointerException());
    }
    if ((email.getToAddresses() == null || email.getToAddresses().size() == 0)
        && (email.getCcAddresses() == null || email.getCcAddresses()
            .size() == 0)
        && (email.getBccAddresses() == null || email.getBccAddresses()
            .size() == 0)) {
      throw new MailException("Please define a recipient email address",
          new NullPointerException());
    }
    if (email.getSubject() == null) {
      throw new MailException("Please define a subject",
          new NullPointerException());
    }
    if (email.getReplyToAddresses() == null
        || email.getReplyToAddresses().size() == 0) {
      email.addReplyTo(email.getFromAddress().getAddress());
    }

    return email;
  }

  public static Session getSession() {
    if (session == null) {
      Properties props = new Properties();
      // Put a bogus value even if we are on dev mode, otherwise JavaMail
      // will complain
      props.put("mail.smtp.host", getConfigOr(
          "mail.smtp.host", "localhost"));

      String channelEncryption;
      if (getConfigOr("mail.smtp.protocol", "smtp").equals("smtps")) {
        // Backward compatibility before stable5
        channelEncryption = "starttls";
      } else {
        channelEncryption = getConfigOr("mail.smtp.channel", "clear");
      }

      if (channelEncryption.equals("clear")) {
        props.put("mail.smtp.port", "25");
      } else if (channelEncryption.equals("ssl")) {
        // port 465 + setup yes ssl socket factory (won't verify that
        // the server certificate is signed with a root ca.)
        props.put("mail.smtp.port", "465");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class",
            "play.utils.YesSSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");
      } else if (channelEncryption.equals("starttls")) {
        // port 25 + enable starttls + ssl socket factory
        props.put("mail.smtp.port", "25");
        props.put("mail.smtp.starttls.enable", "true");
        // can't install our socket factory. will work only with server
        // that has a signed certificate
        // story to be continued in javamail 1.4.2 :
        // https://glassfish.dev.java.net/issues/show_bug.cgi?id=5189
      }

      if (getConfig("mail.smtp.localhost") != null) {
        props.put("mail.smtp.localhost",
            getConfig("mail.smtp.localhost")); // override
                                    // defaults
      }
      String sockfac = getConfig("mail.smtp.socketFactory.class");
      if (sockfac != null) {
        props.put("mail.smtp.socketFactory.class", sockfac);
      }
      String port = getConfig("mail.smtp.port");
      if (port != null) {
        props.put("mail.smtp.port", port);
      }
      String user = getConfigOr("mail.smtp.user", null);
      String password = getConfigOr("mail.smtp.pass", null);
      if (password == null) {
        // Fallback to old convention
        password = getConfigOr("mail.smtp.password", null);
      }
      String authenticator = getConfig("mail.smtp.authenticator");
      session = null;

      if (authenticator != null) {
        props.put("mail.smtp.auth", "true");
        try {
          session = Session.getInstance(
              props,
              (Authenticator) Play.application().classloader().loadClass(authenticator).newInstance());
        } catch (Exception e) {
          Logger.error(
              "Cannot instanciate custom SMTP authenticator: " + authenticator,
              e);
        }
      }

      if (session == null) {
        if (user != null && password != null) {
          props.put("mail.smtp.auth", "true");
          session = Session.getInstance(props, new SMTPAuthenticator(
              user, password));
        } else {
          props.remove("mail.smtp.auth");
          session = Session.getInstance(props);
        }
      }

      if (Boolean.parseBoolean(getConfigOr("mail.debug", "false"))) {
        session.setDebug(true);
      }
    }
    return session;
  }

  /**
   * @author Bing Ran (bing.ran@hotmail.com)
   * @param string
   * @return
   */
  private static String getConfig(String string) {
    return getConfigOr(string, null);
  }

  private static String getConfigOr(String key, String sub) {
    String p = Play.application().configuration().getString(
        key);
    if (p == null)
      p = sub;
    return p;
  }

  /**
   * Send a JavaMail message
   *
   * @param msg
   *            An Email message
   */
  public static Future<Boolean> sendMessage(final Email msg) {
    if (asynchronousSend) {
      return executor.submit(new Callable<Boolean>() {

        public Boolean call() {
          try {
            msg.setSentDate(new Date());
            msg.send();
            return true;
          } catch (Throwable e) {
            MailException me = new MailException(
                "Error while sending email", e);
            Logger.error("The email has not been sent", me);
            return false;
          }
        }
      });
    } else {
      final StringBuffer result = new StringBuffer();
      try {
        msg.setSentDate(new Date());
        msg.send();
      } catch (Throwable e) {
        MailException me = new MailException(
            "Error while sending email", e);
        Logger.error("The email has not been sent", me);
        result.append("oops");
      }
      return new Future<Boolean>() {

        public boolean cancel(boolean mayInterruptIfRunning) {
          return false;
        }

        public boolean isCancelled() {
          return false;
        }

        public boolean isDone() {
          return true;
        }

        public Boolean get() throws InterruptedException,
            ExecutionException {
          return result.length() == 0;
        }

        public Boolean get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException,
            TimeoutException {
          return result.length() == 0;
        }
      };
    }
  }

  static ExecutorService executor = Executors.newCachedThreadPool();

  public static class SMTPAuthenticator extends Authenticator {

    private String user;
    private String password;

    public SMTPAuthenticator(String user, String password) {
      this.user = user;
      this.password = password;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication(user, password);
    }
  }

  public static class Mock {

    static Map<String, String> emails = new HashMap<String, String>();

    public static String getContent(Part message)
        throws MessagingException, IOException {

      if (message.getContent() instanceof String) {
        return message.getContentType() + ": " + message.getContent()
            + " \n\t";
      } else if (message.getContent() != null
          && message.getContent() instanceof Multipart) {
        Multipart part = (Multipart) message.getContent();
        String text = "";
        for (int i = 0; i < part.getCount(); i++) {
          BodyPart bodyPart = part.getBodyPart(i);
          if (!Message.ATTACHMENT.equals(bodyPart.getDisposition())) {
            text += getContent(bodyPart);
          } else {
            text += "attachment: \n"
                + "\t\t name: "
                + (StringUtils.isEmpty(bodyPart.getFileName()) ? "none"
                    : bodyPart.getFileName())
                + "\n"
                + "\t\t disposition: "
                + bodyPart.getDisposition()
                + "\n"
                + "\t\t description: "
                + (StringUtils.isEmpty(bodyPart
                    .getDescription()) ? "none" : bodyPart
                    .getDescription()) + "\n\t";
          }
        }
        return text;
      }
      if (message.getContent() != null
          && message.getContent() instanceof Part) {
        if (!Message.ATTACHMENT.equals(message.getDisposition())) {
          return getContent((Part) message.getContent());
        } else {
          return "attachment: \n"
              + "\t\t name: "
              + (StringUtils.isEmpty(message.getFileName()) ? "none"
                  : message.getFileName())
              + "\n"
              + "\t\t disposition: "
              + message.getDisposition()
              + "\n"
              + "\t\t description: "
              + (StringUtils.isEmpty(message.getDescription()) ? "none"
                  : message.getDescription()) + "\n\t";
        }
      }

      return "";
    }

    static void send(Email email) {

      try {
        final StringBuffer content = new StringBuffer();
        Properties props = new Properties();
        props.put("mail.smtp.host", "myfakesmtpserver.com");

        Session session = Session.getInstance(props);
        email.setMailSession(session);

        email.buildMimeMessage();

        MimeMessage msg = email.getMimeMessage();
        msg.saveChanges();

        String body = getContent(msg);

        content.append("From Mock Mailer\n\tNew email received by");

        content.append("\n\tFrom: "
            + email.getFromAddress().getAddress());
        content.append("\n\tReplyTo: "
            + ((InternetAddress) email.getReplyToAddresses().get(0))
                .getAddress());
        content.append("\n\tTo: ");
        for (Object add : email.getToAddresses()) {
          content.append(add.toString() + ", ");
        }
        // remove the last ,
        content.delete(content.length() - 2, content.length());
        if (email.getCcAddresses() != null
            && !email.getCcAddresses().isEmpty()) {
          content.append("\n\tCc: ");
          for (Object add : email.getCcAddresses()) {
            content.append(add.toString() + ", ");
          }
          // remove the last ,
          content.delete(content.length() - 2, content.length());
        }
        if (email.getBccAddresses() != null
            && !email.getBccAddresses().isEmpty()) {
          content.append("\n\tBcc: ");
          for (Object add : email.getBccAddresses()) {
            content.append(add.toString() + ", ");
          }
          // remove the last ,
          content.delete(content.length() - 2, content.length());
        }
        content.append("\n\tSubject: " + email.getSubject());
        content.append("\n\t" + body);

        content.append("\n");
        Logger.info(content.toString());

        for (Object add : email.getToAddresses()) {
          content.append(", " + add.toString());
          emails.put(((InternetAddress) add).getAddress(),
              content.toString());
        }

      } catch (Exception e) {
        Logger.error("error sending mock email", e);
      }

    }

    public static String getLastMessageReceivedBy(String email) {
      return emails.get(email);
    }

    public static void reset() {
      emails.clear();
    }
  }
}
TOP

Related Classes of cn.bran.play.Mail$SMTPAuthenticator

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.