Package com.agiletec.plugins.jpmail.aps.services.mail

Source Code of com.agiletec.plugins.jpmail.aps.services.mail.MailManager

/*
*
* Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved.
*
* This file is part of Entando software.
* Entando is a free software;
* You can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation; version 2.
*
* See the file License for the specific language governing permissions  
* and limitations under the License
*
*
*
* Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved.
*
*/
package com.agiletec.plugins.jpmail.aps.services.mail;

import com.agiletec.aps.system.ApsSystemUtils;
import com.agiletec.aps.system.common.AbstractService;
import com.agiletec.aps.system.exception.ApsSystemException;
import com.agiletec.aps.system.services.baseconfig.ConfigInterface;
import com.agiletec.plugins.jpmail.aps.services.JpmailSystemConstants;
import com.agiletec.plugins.jpmail.aps.services.mail.parse.MailConfigDOM;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;
import java.util.Map.Entry;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;


/**
* Implementation for the manager providing email sending functions.
*
* @author E.Santoboni, E.Mezzano
*/
public class MailManager extends AbstractService implements IMailManager {

  @Override
  public void init() throws Exception {
    this.loadConfigs();
    ApsSystemUtils.getLogger().debug(this.getClass().getName() + ": initialized; mail sender active : " + isActive());
  }

  /**
   * Load the XML configuration containing smtp configuration and the sender
   * addresses.
   *
   * @throws ApsSystemException
   */
  private void loadConfigs() throws ApsSystemException {
    try {
      ConfigInterface configManager = this.getConfigManager();
      String xml = configManager.getConfigItem(JpmailSystemConstants.MAIL_CONFIG_ITEM);
      if (xml == null) {
        throw new ApsSystemException("Configuration item not present: " + JpmailSystemConstants.MAIL_CONFIG_ITEM);
      }
      MailConfigDOM configDOM = new MailConfigDOM();
      this.setConfig(configDOM.extractConfig(xml));
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "loadConfigs");
      throw new ApsSystemException("Errore in fase di inizializzazione", t);
    }
  }

  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#getMailConfig()
   */
  @Override
  public MailConfig getMailConfig() throws ApsSystemException {
    try {
      return (MailConfig) this._config.clone();
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "getMailConfig");
      throw new ApsSystemException("Error loading mail service configuration", t);
    }
  }

  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#updateMailConfig(com.agiletec.plugins.jpmail.aps.services.mail.MailConfig)
   */
  @Override
  public void updateMailConfig(MailConfig config) throws ApsSystemException {
    try {
      String xml = new MailConfigDOM().createConfigXml(config);
      this.getConfigManager().updateConfigItem(JpmailSystemConstants.MAIL_CONFIG_ITEM, xml);
      this.setConfig(config);
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "updateMailConfig");
      throw new ApsSystemException("Errore in fase di aggiornamento configurazione mail", t);
    }
  }

  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#sendMail(java.lang.String, java.lang.String, java.lang.String[], java.lang.String[], java.lang.String[], java.lang.String)
   */
  @Override
  public boolean sendMail(String text, String subject, String[] recipientsTo,
      String[] recipientsCc, String[] recipientsBcc, String senderCode) throws ApsSystemException {
    return this.sendMail(text, subject, CONTENTTYPE_TEXT_PLAIN, null, recipientsTo, recipientsCc, recipientsBcc, senderCode);
  }

  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#sendMail(java.lang.String, java.lang.String, java.lang.String[], java.lang.String[], java.lang.String[], java.lang.String, java.lang.String)
   */
  @Override
  public boolean sendMail(String text, String subject, String[] recipientsTo,
      String[] recipientsCc, String[] recipientsBcc, String senderCode, String contentType) throws ApsSystemException {
    return this.sendMail(text, subject, contentType, null, recipientsTo, recipientsCc, recipientsBcc, senderCode);
  }

  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#smtpServerTest(com.agiletec.plugins.jpmail.aps.services.mail.MailConfig)
   */
  @Override
  public boolean smtpServerTest(MailConfig mailConfig) {
    try {
      Properties props = new Properties();
      Session session = prepareSession(mailConfig);
      Transport transport = prepareTransport(session, mailConfig);
      transport.connect(mailConfig.getSmtpHost(), mailConfig.getSmtpPort(), mailConfig.getSmtpUserName(), mailConfig.getSmtpPassword());
      transport.close();
      return true;
    } catch (Exception e) {
      ApsSystemUtils.logThrowable(e, this, "smtpServerTest - smtpServerTest");
      return false;
    }
  }

  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#sendMail(java.lang.String, java.lang.String, java.lang.String, java.util.Properties, java.lang.String[], java.lang.String[], java.lang.String[], java.lang.String)
   */
  @Override
  public boolean sendMail(String text, String subject, String contentType, Properties attachmentFiles, String[] recipientsTo,
      String[] recipientsCc, String[] recipientsBcc, String senderCode) throws ApsSystemException {
    if (!isActive()) {
      ApsSystemUtils.getLogger().info("Sender function disabled : mail Subject " + subject);
      return true;
    }
    return send(text, subject, recipientsTo, recipientsCc, recipientsBcc, senderCode, attachmentFiles, contentType);
  }
 
  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#sendMailForTest(java.lang.String, java.lang.String, java.lang.String[], java.lang.String)
   */
  @Override
  public boolean sendMailForTest(String text, String subject, String[] recipientsTo, String senderCode) throws ApsSystemException {
    return this.send(text, subject, recipientsTo, null, null, senderCode,null, CONTENTTYPE_TEXT_PLAIN);
  }
 
  private boolean send(String text, String subject, String[] recipientsTo, String[] recipientsCc, String[] recipientsBcc, String senderCode, Properties attachmentFiles, String contentType) throws ApsSystemException {
    Transport bus = null;
    try {
      Session session = this.prepareSession(this.getConfig());
      bus = this.prepareTransport(session, this.getConfig());
      MimeMessage msg = this.prepareVoidMimeMessage(session, subject, recipientsTo, recipientsCc, recipientsBcc, senderCode);

      if (attachmentFiles == null || attachmentFiles.isEmpty()) {
        msg.setContent(text, contentType + "; charset=utf-8");
      } else {
        Multipart multiPart = new MimeMultipart();
        this.addBodyPart(text, contentType, multiPart);
        this.addAttachments(attachmentFiles, multiPart);
        msg.setContent(multiPart);
      }
      msg.saveChanges();
      bus.send(msg);
    } catch (Throwable t) {
      throw new ApsSystemException("Errore in spedizione mail", t);
    } finally {
      closeTransport(bus);
    }
    return true;
  }
 
  /* (non-Javadoc)
   * @see com.agiletec.plugins.jpmail.aps.services.mail.IMailManager#sendMixedMail(java.lang.String, java.lang.String, java.lang.String, java.util.Properties, java.lang.String[], java.lang.String[], java.lang.String[], java.lang.String)
   */
  @Override
  public boolean sendMixedMail(String simpleText, String htmlText, String subject, Properties attachmentFiles,
      String[] recipientsTo, String[] recipientsCc, String[] recipientsBcc, String senderCode) throws ApsSystemException {
    if (!isActive()) {
      ApsSystemUtils.getLogger().info("Sender function disabled : mail Subject " + subject);
      return true;
    }
    Transport bus = null;
    try {
      Session session = this.prepareSession(this.getConfig());
      bus = this.prepareTransport(session, this.getConfig());
      MimeMessage msg = this.prepareVoidMimeMessage(session, subject, recipientsTo, recipientsCc, recipientsBcc, senderCode);

      boolean hasAttachments = attachmentFiles != null && attachmentFiles.size() > 0;
      String multipartMimeType = hasAttachments ? "mixed" : "alternative";
      MimeMultipart multiPart = new MimeMultipart(multipartMimeType);

      this.addBodyPart(simpleText, CONTENTTYPE_TEXT_PLAIN, multiPart);
      this.addBodyPart(htmlText, CONTENTTYPE_TEXT_HTML, multiPart);
      if (hasAttachments) {
        this.addAttachments(attachmentFiles, multiPart);
      }
      msg.setContent(multiPart);
      msg.saveChanges();
      bus.send(msg);
    } catch (Throwable t) {
      throw new ApsSystemException("Errore in spedizione mail", t);
    } finally {
      closeTransport(bus);
    }
    return true;
  }

  /**
   * Prepare a Transport object ready for use.
   *
   * @param session A session object.
   * @return The Transport object ready for use.
   * @throws Exception In case of errors opening the Transport object.
   */
  protected Transport prepareTransport(Session session, MailConfig config) throws Exception {
    Transport bus = session.getTransport("smtp");
    if (config.hasAnonimousAuth()) {
      bus.connect();
    }
    return bus;
  }

  /**
   * Prepare a Session object ready for use.
   *
   * @return The Session object ready for use.
   */
  protected Session prepareSession(MailConfig config) {
    Properties props = new Properties();
    Session session = null;
    // Timeout
    int timeout = DEFAULT_SMTP_TIMEOUT;
    Integer timeoutParam = config.getSmtpTimeout();
    if (null != timeoutParam && timeoutParam.intValue() != 0) {
      timeout = timeoutParam;
    }
    props.put("mail.smtp.connectiontimeout", timeout);
    props.put("mail.smtp.timeout", timeout);
    // Debug
    if (config.isDebug()) {
      props.put("mail.debug", "true");
    }
    // port
    Integer port = config.getSmtpPort();
    if (null != port && port.intValue() > 0) {
      props.put("mail.smtp.port", port.toString());
    } else {
      props.put("mail.smtp.port", JpmailSystemConstants.DEFAULT_SMTP_PORT.toString());
    }
    // host
    props.put("mail.smtp.host", config.getSmtpHost());
    // auth
    if (!config.hasAnonimousAuth()) {
      props.put("mail.smtp.auth", "true");
      switch (config.getSmtpProtocol()) {
        case JpmailSystemConstants.PROTO_SSL:
          props.put("mail.smtp.socketFactory.port", port);
          props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
          props.put("mail.transport.protocol", "smtps");
          break;
        case JpmailSystemConstants.PROTO_TLS:
          props.put("mail.smtp.starttls.enable", "true");
          break;
        case JpmailSystemConstants.PROTO_STD:
        // do nothing just use previous properties WITH the authenticator
      }
      Authenticator auth = new SMTPAuthenticator(config);
      session = Session.getInstance(props, auth);
    } else {
      session = Session.getDefaultInstance(props);
    }
    return session;
  }

  /**
   * Prepare a MimeMessage complete of sender, recipient addresses, subject
   * and current date but lacking in the message text content.
   *
   * @param session The session object.
   * @param subject The e-mail subject.
   * @param recipientsTo The e-mail main destination addresses.
   * @param recipientsCc The e-mail 'carbon-copy' destination addresses.
   * @param recipientsBcc The e-mail 'blind carbon-copy' destination
   * addresses.
   * @param senderCode The sender code, as configured in the service
   * configuration.
   * @return A mime message without message text content.
   * @throws AddressException In case of non-valid e-mail addresses.
   * @throws MessagingException In case of errors preparing the mail message.
   */
  protected MimeMessage prepareVoidMimeMessage(Session session, String subject, String[] recipientsTo,
      String[] recipientsCc, String[] recipientsBcc, String senderCode) throws AddressException, MessagingException {
    MimeMessage msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(this.getConfig().getSender(senderCode)));
    msg.setSubject(subject);
    msg.setSentDate(new Date());

    this.addRecipients(msg, Message.RecipientType.TO, recipientsTo);
    this.addRecipients(msg, Message.RecipientType.CC, recipientsCc);
    this.addRecipients(msg, Message.RecipientType.BCC, recipientsBcc);

    msg.saveChanges();
    return msg;
  }

  /**
   * Add a BodyPart to the Multipart container.
   *
   * @param text The text content.
   * @param contentType The text contentType.
   * @param multiPart The Multipart container.
   * @throws MessagingException In case of errors adding the body part.
   */
  protected void addBodyPart(String text, String contentType, Multipart multiPart) throws MessagingException {
    MimeBodyPart textBodyPart = new MimeBodyPart();
    textBodyPart.setContent(text, contentType + "; charset=utf-8");
    multiPart.addBodyPart(textBodyPart);
  }

  /**
   * Add the attachments to the Multipart container.
   *
   * @param attachmentFiles The attachments mapped as fileName/filePath.
   * @param multiPart The Multipart container.
   * @throws MessagingException In case of errors adding the attachments.
   */
  protected void addAttachments(Properties attachmentFiles, Multipart multiPart) throws MessagingException {
    Iterator filesIter = attachmentFiles.entrySet().iterator();
    while (filesIter.hasNext()) {
      Entry fileEntry = (Entry) filesIter.next();
      MimeBodyPart fileBodyPart = new MimeBodyPart();
      DataSource dataSource = new FileDataSource((String) fileEntry.getValue());
      fileBodyPart.setDataHandler(new DataHandler(dataSource));
      fileBodyPart.setFileName((String) fileEntry.getKey());
      multiPart.addBodyPart(fileBodyPart);
    }
  }

  /**
   * Add recipient addresses to the e-mail.
   *
   * @param msg The mime message to which add the addresses.
   * @param recType The specific recipient type to which add the addresses.
   * @param recipients The recipient addresses.
   */
  protected void addRecipients(MimeMessage msg, RecipientType recType, String[] recipients) {
    if (null != recipients) {
      try {
        Address[] addresses = new Address[recipients.length];
        for (int i = 0; i < recipients.length; i++) {
          Address address = new InternetAddress(recipients[i]);
          addresses[i] = address;
        }
        msg.setRecipients(recType, addresses);
      } catch (MessagingException e) {
        throw new RuntimeException("Errore in aggiunta recipients", e);
      }
    }
  }

  /**
   * Close the transport.
   *
   * @param transport The transport.
   * @throws ApsSystemException In case of errors closing the transport.
   */
  protected void closeTransport(Transport transport) throws ApsSystemException {
    if (transport != null) {
      try {
        transport.close();
      } catch (MessagingException e) {
        throw new ApsSystemException("Errore in chiusura connessione", e);
      }
    }
  }

  /**
   * returns the mail service configuration.
   *
   * @return The mail service configuration.
   */
  protected MailConfig getConfig() {
    return _config;
  }

  /**
   * Set the mail service configuration.
   *
   * @param config The mail service configuration.
   */
  protected void setConfig(MailConfig config) {
    this._config = config;
  }

  protected Boolean isActive() {
    if (null != this._active) {
      return this._active.booleanValue();
    }
    return this.getConfig().isActive();
  }

  public void setActive(Boolean active) {
    this._active = active;
  }

  /**
   * Returns the configuration manager.
   *
   * @return The Configuration manager.
   */
  protected ConfigInterface getConfigManager() {
    return _configManager;
  }

  /**
   * Set method for Spring bean injection.<br /> Set the Configuration
   * manager.
   *
   * @param configManager The Configuration manager.
   */
  public void setConfigManager(ConfigInterface configManager) {
    this._configManager = configManager;
  }
  private Boolean _active;
  private MailConfig _config;
  private ConfigInterface _configManager;
  /*
   * Default Timeout in milliseconds
   */
  public static final int DEFAULT_SMTP_TIMEOUT = 5000;

}
TOP

Related Classes of com.agiletec.plugins.jpmail.aps.services.mail.MailManager

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.