All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.anaptecs.jeaf.serviceproviders.mail.MailServiceProviderImpl Maven / Gradle / Ivy

The newest version!
/*
 * anaptecs GmbH, Burgstr. 96, 72764 Reutlingen, Germany
 * 
 * Copyright 2004 - 2015 All rights reserved.
 */
package com.anaptecs.jeaf.serviceproviders.mail;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.anaptecs.jeaf.spi.mail.MailServiceProvider;
import com.anaptecs.jeaf.spi.mail.MailServiceProviderMessages;
import com.anaptecs.jeaf.spi.mail.MailSystemException;
import com.anaptecs.jeaf.tools.api.Tools;
import com.anaptecs.jeaf.xfun.api.XFun;
import com.anaptecs.jeaf.xfun.api.checks.Assert;
import com.anaptecs.jeaf.xfun.api.checks.Check;
import com.anaptecs.jeaf.xfun.api.errorhandling.ErrorCode;
import com.anaptecs.jeaf.xfun.api.errorhandling.FailureMessage;
import com.anaptecs.jeaf.xfun.api.errorhandling.JEAFSystemException;
import com.anaptecs.jeaf.xfun.api.errorhandling.SystemException;
import com.anaptecs.jeaf.xfun.api.health.CheckLevel;
import com.anaptecs.jeaf.xfun.api.health.HealthCheckResult;
import com.anaptecs.jeaf.xfun.api.health.HealthStatus;
import com.anaptecs.jeaf.xfun.api.info.RuntimeEnvironment;
import com.anaptecs.jeaf.xfun.api.trace.Trace;
import com.sun.mail.smtp.SMTPTransport;

/**
 * This class is an implementation of JEAF's MailServiceProvider interface.
 * 
 * @author JEAF Development Team
 * @version 1.0
 */
final class MailServiceProviderImpl extends MailServiceProviderImplBase implements MailServiceProvider {

  /** The Constant DEFAULT_MAIL_DEBUG. */
  private static final boolean DEFAULT_MAIL_DEBUG = false;

  /** The Constant DEFAULT_MAIL_FROM. */
  private static final String DEFAULT_MAIL_FROM = "";

  /** The Constant DEFAULT_MAIL_SMTP_AUTH. */
  private static final boolean DEFAULT_MAIL_SMTP_AUTH = false;

  /** The Constant DEFAULT_MAIL_SMTP_HOST. */
  private static final String DEFAULT_MAIL_SMTP_HOST = "localhost";

  /** The Constant DEFAULT_MAIL_SMTP_PASSWORD. */
  private static final String DEFAULT_MAIL_SMTP_PASSWORD = "";

  /** The Constant DEFAULT_MAIL_SMTP_PORT. */
  private static final int DEFAULT_MAIL_SMTP_PORT = 25;

  /** The Constant DEFAULT_MAIL_SMTP_SENDPARTIAL. */
  private static final boolean DEFAULT_MAIL_SMTP_SENDPARTIAL = false;

  /** The Constant DEFAULT_MAIL_SMTP_SSL_ENABLE. */
  private static final boolean DEFAULT_MAIL_SMTP_SSL_ENABLE = false;

  /** The Constant DEFAULT_MAIL_SMTP_STARTTLS_ENABLE. */
  private static final boolean DEFAULT_MAIL_SMTP_STARTTLS_ENABLE = false;

  /** The Constant DEFAULT_MAIL_SMTP_USER. */
  private static final String DEFAULT_MAIL_SMTP_USER = "";

  /** The Constant DEFAULT_MAIL_STORE_PROTOCOL. */
  private static final String DEFAULT_MAIL_STORE_PROTOCOL = "pop3";

  /** The Constant DEFAULT_MAIL_TANSPORT_PROTOCOL. */
  private static final String DEFAULT_MAIL_TANSPORT_PROTOCOL = "smtp";

  /**
   * Session that will be used to send an e-mail. Actually the session should be set in the initialize method. However
   * this is not possible due to the fact that properties are not accessible at this phase of the bootstrapping of JEAF.
   * Thus the session is loaded lazy. To retrieve a session method getSession has to be used.
   */
  private Session session;

  /**
   * Constructor has reduced visibility in order to ensure that all service provider implementations are created through
   * the factory.
   */
  MailServiceProviderImpl( ) {
  }

  /**
   * Method checks the current state of the service provider. Therefore JEAF defines three different check levels:
   * internal Checks, infrastructure checks and external checks. For further details about the check levels
   * {@see CheckLevel}. This service does not implement any checks.
   * 
   * @param pLevel Check level on which the check should be performed. Parameter will be ignored.
   * @return {@link CheckResult} Since the method does not implement any checks it will always return null.
   */
  public HealthCheckResult check( CheckLevel pLevel ) {
    List lWarnings = new ArrayList(1);
    List lErrors = new ArrayList(1);

    // Check if sending of mails is disabled. This will cause a warning.
    if (this.getMailDisableSending() == true) {
      FailureMessage lWarning = new FailureMessage(MailServiceProviderMessages.SENDING_MAILS_DISABLED, null, null);
      lWarnings.add(lWarning);
    }

    // Check if sender mail address is set. This will cause an error.
    if (this.getMailFrom() == null) {
      FailureMessage lError = new FailureMessage(MailServiceProviderMessages.MAIL_FROM_NO_SET, null, null);
      lErrors.add(lError);
    }

    // Check if mail from personal is not set. This will cause an warning.
    if (this.getMailFromPersonal() == null) {
      FailureMessage lWarning = new FailureMessage(MailServiceProviderMessages.MAIL_FROM_PERSONAL_NO_SET, null, null);
      lWarnings.add(lWarning);
    }
    return new HealthCheckResult(HealthStatus.ERROR, lWarnings, lErrors);
  }

  /**
   * This method will be called at startup by JEAF and enables the service provider to perform its specific
   * initialization routines.
   * 
   * @throws SystemException Service provider specific exception in order to show that the initialization was not
   * successful.
   */
  public void initialize( ) throws SystemException {
    // Nothing what we can do here.
  }

  /**
   * Method sends an e-mail using the passed message object. The subject, content and recipients of the message have to
   * be specified inside the passed message object.
   * 
   * @param pMessage Message to be sent. The parameter must not be null.
   */
  public void sendMail( Message pMessage ) {
    // Check parameter.
    Check.checkInvalidParameterNull(pMessage, "pMessage");

    SMTPTransport lSMTPTransport = null;

    // Send the message.
    try {
      // Prepare trace message
      Trace lTrace = XFun.getTrace();
      List
lAllRecipients = Arrays.asList(pMessage.getAllRecipients()); String lSubject = pMessage.getSubject(); if (this.getMailDisableSending() == false) { // Trace message. lTrace.write(MailServiceProviderMessages.SENDING_MAIL, lSubject, lAllRecipients.toString()); // Get the transport and establish the connection Session lSession = this.getSession(); lSMTPTransport = (SMTPTransport) lSession.getTransport(); boolean lAuthentictionRequired = this.getMailSmtpAuth(); String lHost = lSession.getProperty(JavaMailConstants.MAIL_SMTP_HOST); int lPort = Integer.valueOf(lSession.getProperty(JavaMailConstants.MAIL_SMTP_PORT)).intValue(); if (lAuthentictionRequired == true) { String lUser = lSession.getProperty(JavaMailConstants.MAIL_SMTP_USER); String lPassword = lSession.getProperty(JavaMailConstants.MAIL_SMTP_PASSWORD); lTrace.debug("Establishing connection to smtp server " + lHost + ":" + lPort + " with user " + lUser); lSMTPTransport.connect(lHost, lPort, lUser, lPassword); } else { lTrace.debug("Establishing anonymous connection to smtp server " + lHost + ":" + lPort); lSMTPTransport.connect(lHost, lPort, null, null); } // Send the message through SMTP transport lSMTPTransport.sendMessage(pMessage, pMessage.getAllRecipients()); } // Just write trace message that mail was not send as sending is disabled. else { lTrace.write(MailServiceProviderMessages.NOT_SENDING_MAIL, lSubject, lAllRecipients.toString()); } } catch (MessagingException e) { throw new MailSystemException(MailServiceProviderMessages.MAIL_MESSAGE_SEND_ERROR, e, e.getLocalizedMessage()); } finally { // Close SMTP transport if necessary if (lSMTPTransport != null && lSMTPTransport.isConnected()) { try { lSMTPTransport.close(); } catch (MessagingException e) { throw new MailSystemException(MailServiceProviderMessages.MAIL_MESSAGE_SEND_ERROR, e, e.getLocalizedMessage()); } } } } /** * Method sends an e-mail using a newly created message with the passed subject, content and recipients objects. * * @param pContent The content of the message. The parameter can be empty but must not be null. * @param pSubject The subject of the message. The parameter can be empty but must not be null. * @param pRecipients The recipients of the message. The parameter must at least contain one valid * Address and must not be null. */ public void sendMail( String pContent, String pSubject, Set
pRecipients ) { // Check parameters. Check.checkInvalidParameterNull(pContent, "pContent"); Check.checkInvalidParameterNull(pSubject, "pSubject"); Check.checkInvalidParameterNull(pRecipients, "pRecipients"); // Create the MimeMessage. Message lMessage = this.createMessage(pContent, pSubject, pRecipients); // Send the message. this.sendMail(lMessage); } /** * Method creates and returns an empty message object. * * @return {@link MimeMessage} An empty MimeMessage. The method must not return null. */ public MimeMessage createMessage( ) { // Create new message and use sender address that is defined as property. Session lSession = this.getSession(); MimeMessage lMessage = new MimeMessage(lSession); try { String lMailFrom = this.getMailFrom(); Assert.assertNotNull(lMailFrom, "Dynamic Property 'mailFrom'"); InternetAddress lAddress = new InternetAddress(lMailFrom); String lMailFromPersonal = this.getMailFromPersonal(); if (lMailFromPersonal != null) { lAddress.setPersonal(lMailFromPersonal); } lMessage.setFrom(lAddress); } catch (MessagingException e) { final ErrorCode lErrorCode = MailServiceProviderMessages.MAIL_MESSAGE_SET_FIELD_ERROR; throw new MailSystemException(lErrorCode, e); } catch (UnsupportedEncodingException e) { final ErrorCode lErrorCode = MailServiceProviderMessages.MAIL_MESSAGE_SET_FIELD_ERROR; throw new MailSystemException(lErrorCode, e); } return lMessage; } /** * Method creates and returns a message object using the passed content, subject and recipients objects. * * @param pContent The content of the message. The parameter can be empty but must not be null. * @param pSubject The subject of the message. The parameter can be empty but must not be null. * @param pRecipients The recipients of the message. The parameter must at least contain one valid * Address and must not be null. * @return {@link MimeMessage} A MimeMessage filled with the passed parameters. The method must not * return null. */ public MimeMessage createMessage( String pContent, String pSubject, Set
pRecipients ) { // Check parameters. Check.checkInvalidParameterNull(pContent, "pContent"); Check.checkInvalidParameterNull(pSubject, "pSubject"); Check.checkInvalidParameterNull(pRecipients, "pRecipients"); try { // Create an empty message object. MimeMessage lMailMessage = this.createMessage(); // Fill the empty message object with the passed parameters. lMailMessage.setSubject(pSubject); lMailMessage.setText(pContent); lMailMessage.setSentDate(new Date()); for (Address bAddress : pRecipients) { lMailMessage.addRecipient(RecipientType.TO, bAddress); } // Return create mail message. return lMailMessage; } catch (MessagingException e) { final ErrorCode lErrorCode = MailServiceProviderMessages.MAIL_MESSAGE_SET_FIELD_ERROR; throw new MailSystemException(lErrorCode, e); } } /** * Method returns the mail session that can be used to create and send messages. * * @return {@link Session} Session that can be used to create a message. The method never returns null. */ private synchronized Session getSession( ) { // Check if session is still working. if (session != null) { String lMailTransportProtocol = this.getMailTransportProtocol(); try { // Check if session is connected. If not any more than we need a new session. Transport lTransport = session.getTransport(lMailTransportProtocol); boolean lConnected = lTransport.isConnected(); if (lConnected == false) { session = null; XFun.getTrace().info("Invalidating current mail session as it is not connected any more."); } } // Unable to create transport object. This might be a configuration problem. catch (MessagingException e) { throw new MailSystemException(MailServiceProviderMessages.MAIL_MESSAGE_SEND_ERROR, e, e.getLocalizedMessage()); } } // Currently no mail session is available. So we have to create one. if (session == null) { XFun.getTrace().info("Trying to create a new mail session."); // Execute platform dependent "lookup" for a session. RuntimeEnvironment lRuntimeEnvironment = XFun.getInfoProvider().getRuntimeEnvironment(); switch (lRuntimeEnvironment) { // In JavaSE environments the session has to be created using a Properties object. // The transport object is created using the transport protocol specified in the properties. case JSE: Properties lJSEProperties = this.loadJavaSEProperties(); session = Session.getInstance(lJSEProperties); break; // Within the EJB container a JNDI lookup for the session has to be performed. // The transport object is created using the transport protocol specified in the application server's // configuration. If the JNDI path is not specified a fallback is performed that creates the session using a // Properties object. case EJB_CONTAINER: // Get mailSessionJNDI Property String lMailSessionJndi = this.getMailSessionJNDI(); if (Tools.getStringTools().isBlank(lMailSessionJndi)) { Properties lEJBProperties = this.loadJavaSEProperties(); session = Session.getInstance(lEJBProperties); } else { try { InitialContext lContext = new InitialContext(); session = (Session) lContext.lookup(lMailSessionJndi); lContext.close(); } catch (NamingException e) { throw new JEAFSystemException(MailServiceProviderMessages.MAIL_JNDI_LOOKUP_ERROR, e, lMailSessionJndi); } } break; // All other environments are currently not supported for the use with this service provider implementation. default: throw new JEAFSystemException(MailServiceProviderMessages.UNSUPPORTED_RUNTIME, lRuntimeEnvironment.toString()); } } // Return existing session return session; } /** * Loads the MailServiceProvider property list. This method should be used for a JavaSE Runtime Environment. * * @return {@link Properties} A property list. The method must not return null. */ private Properties loadJavaSEProperties( ) { // Prevent the getters from passing on null to the property list by instead using default values. boolean lMailDebug = this.getMailDebug() == null ? DEFAULT_MAIL_DEBUG : this.getMailDebug(); String lMailFrom = Tools.getStringTools().isBlank(this.getMailFrom()) ? DEFAULT_MAIL_FROM : this.getMailFrom(); boolean lMailSmtpAuth = this.getMailSmtpAuth() == null ? DEFAULT_MAIL_SMTP_AUTH : this.getMailSmtpAuth(); String lMailSmtpHost = Tools.getStringTools().isBlank(this.getMailSmtpHost()) ? DEFAULT_MAIL_SMTP_HOST : this.getMailSmtpHost(); int lMailSmtpPort = this.getMailSmtpPort() == null ? DEFAULT_MAIL_SMTP_PORT : this.getMailSmtpPort(); boolean lMailSmtpSendpartial = this.getMailSmtpSendpartial() == null ? DEFAULT_MAIL_SMTP_SENDPARTIAL : this.getMailSmtpSendpartial(); String lMailSmtpPassword = Tools.getStringTools().isBlank(this.getMailSmtpPassword()) ? DEFAULT_MAIL_SMTP_PASSWORD : this.getMailSmtpPassword(); String lMailSmtpUser = Tools.getStringTools().isBlank(this.getMailSmtpUser()) ? DEFAULT_MAIL_SMTP_USER : this.getMailSmtpUser(); String lMailStoreProtocol = Tools.getStringTools().isBlank(this.getMailStoreProtocol()) ? DEFAULT_MAIL_STORE_PROTOCOL : this.getMailStoreProtocol(); String lMailTransportProtocol = Tools.getStringTools().isBlank(this.getMailTransportProtocol()) ? DEFAULT_MAIL_TANSPORT_PROTOCOL : this.getMailTransportProtocol(); boolean lMailSmtpStarttlsEnable = this.getMailSmtpStarttlsEnable() == null ? DEFAULT_MAIL_SMTP_STARTTLS_ENABLE : this.getMailSmtpStarttlsEnable(); boolean lMailSmtpSslEnable = this.getMailSmtpSslEnable() == null ? DEFAULT_MAIL_SMTP_SSL_ENABLE : this.getMailSmtpSslEnable(); // Add the values from the getters to the property list. Properties lProperties = new Properties(); lProperties.setProperty(JavaMailConstants.MAIL_DEBUG, Boolean.toString(lMailDebug)); lProperties.setProperty(JavaMailConstants.MAIL_FROM, lMailFrom); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_AUTH, Boolean.toString(lMailSmtpAuth)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_AUTH_PLAIN_DISABLE, Boolean.toString(false)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_AUTH_LOGIN_DISABLE, Boolean.toString(false)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_AUTH_DIGESTMD5_DISABLE, Boolean.toString(true)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_AUTH_NTLM_DISABLE, Boolean.toString(true)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_HOST, lMailSmtpHost); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_PASSWORD, lMailSmtpPassword); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_PORT, Integer.toString(lMailSmtpPort)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_SENDPARTIAL, Boolean.toString(lMailSmtpSendpartial)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_STARTTLS_ENABLE, Boolean.toString(lMailSmtpStarttlsEnable)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_SSL_ENABLE, Boolean.toString(lMailSmtpSslEnable)); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_USER, lMailSmtpUser); lProperties.setProperty(JavaMailConstants.MAIL_STORE_PROTOCOL, lMailStoreProtocol); lProperties.setProperty(JavaMailConstants.MAIL_TRANSPORT_PROTOCOL, lMailTransportProtocol); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_TIMEOUT, "60000"); lProperties.setProperty(JavaMailConstants.MAIL_SMTP_CONNECTIONTIMEOUT, "60000"); lProperties.setProperty(JavaMailConstants.MAIL_USER, lMailSmtpUser); lProperties.setProperty(JavaMailConstants.MAIL_PASSWORD, lMailSmtpPassword); return lProperties; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy