/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * * Copyright 2006 - 2013 Pentaho Corporation. All rights reserved. */ package org.pentaho.platform.plugin.services.email; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.pentaho.platform.api.email.IEmailConfiguration; import org.pentaho.platform.api.email.IEmailService; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.plugin.services.messages.Messages; import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import java.util.Properties; /** * Manages the email connection information * * @author <a href="mailto:dkincade@pentaho.com">David M. Kincade</a> */ public class EmailService implements IEmailService { /** * Messages class */ private static final Messages messages = Messages.getInstance(); /** * The location of the default email configuration file */ private static final String DEFAULT_EMAIL_CONFIG_PATH = "system" + File.separator + "smtp-email" + File.separator + "email_config.xml"; /** * The logger for this class */ private static final Log logger = LogFactory.getLog( EmailService.class ); /** * The file which contains the email configuration information. This is guaranteed to be NOT NULL by the * setEmailConfigFile() method */ private File emailConfigFile; /** * Constructs an instance of this class using the default settings location as defined by PentahoSystem * * @throws IllegalArgumentException * Indicates that the default location for the email configuration file is invalid */ public EmailService() throws IllegalArgumentException { logger.debug( "Using the default email configuration filename [" + DEFAULT_EMAIL_CONFIG_PATH + "]" ); final String emailConfigFilePath = PentahoSystem.getApplicationContext().getSolutionPath( DEFAULT_EMAIL_CONFIG_PATH ); logger.debug( "System converted default email configuration filename to [" + emailConfigFilePath + "]" ); setEmailConfigFile( new File( emailConfigFilePath ) ); } /** * Constructs an instance of this class using the specified file location as the source of the email configuration * * @param emailConfigFile * the file reference to the email configuration * @throws IllegalArgumentException * indicates the argument is either null or references a location which is invalid (the parent folder of the * specified file doesn't exist) */ public EmailService( final File emailConfigFile ) throws IllegalArgumentException { setEmailConfigFile( emailConfigFile ); } public void setEmailConfig( final IEmailConfiguration emailConfiguration ) { if ( emailConfiguration == null ) { throw new IllegalArgumentException( messages.getErrorString( "EmailService.ERROR_0002_NULL_CONFIGURATION" ) ); } final Document document = EmailConfigurationXml.getDocument( emailConfiguration ); try { emailConfigFile.createNewFile(); final FileOutputStream fileOutputStream = new FileOutputStream( emailConfigFile ); XmlDom4JHelper.saveDom( document, fileOutputStream, "UTF-8" ); fileOutputStream.close(); } catch ( IOException e ) { logger.error( messages.getErrorString( "EmailService.ERROR_0003_ERROR_CREATING_EMAIL_CONFIG_FILE", e .getLocalizedMessage() ) ); } } /** * TODO document * * @return */ public EmailConfiguration getEmailConfig() { try { return new EmailConfigurationXml( emailConfigFile ); } catch ( Exception e ) { logger.error( messages.getErrorString( "EmailService.ERROR_0004_LOADING_EMAIL_CONFIG_FILE", e .getLocalizedMessage() ) ); return new EmailConfiguration(); } } /** * Tests the provided email configuration by sending a test email. This will just indicate that the server * configuration is correct and a test email was successfully sent. It does not test the destination address. * * @param emailConfig * the email configuration to test * @throws Exception * indicates an error running the test (as in an invalid configuration) */ public String sendEmailTest( final IEmailConfiguration emailConfig ) { final Properties emailProperties = new Properties(); emailProperties.setProperty( "mail.smtp.host", emailConfig.getSmtpHost() ); emailProperties.setProperty( "mail.smtp.port", ObjectUtils.toString( emailConfig.getSmtpPort() ) ); emailProperties.setProperty( "mail.transport.protocol", emailConfig.getSmtpProtocol() ); emailProperties.setProperty( "mail.smtp.starttls.enable", ObjectUtils.toString( emailConfig.isUseStartTls() ) ); emailProperties.setProperty( "mail.smtp.auth", ObjectUtils.toString( emailConfig.isAuthenticate() ) ); emailProperties.setProperty( "mail.smtp.ssl", ObjectUtils.toString( emailConfig.isUseSsl() ) ); emailProperties.setProperty( "mail.debug", ObjectUtils.toString( emailConfig.isDebug() ) ); Session session = null; if ( emailConfig.isAuthenticate() ) { Authenticator authenticator = new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( emailConfig.getUserId(), emailConfig.getPassword() ); } }; session = Session.getInstance( emailProperties, authenticator ); } else { session = Session.getInstance( emailProperties ); } String sendEmailMessage = ""; try { MimeMessage msg = new MimeMessage( session ); msg.setFrom( new InternetAddress( emailConfig.getDefaultFrom(), emailConfig.getFromName() ) ); msg.setRecipients( Message.RecipientType.TO, InternetAddress.parse( emailConfig.getDefaultFrom() ) ); msg.setSubject( messages.getString( "EmailService.SUBJECT" ) ); msg.setText( messages.getString( "EmailService.MESSAGE" ) ); msg.setHeader( "X-Mailer", "smtpsend" ); msg.setSentDate( new Date() ); Transport.send( msg ); sendEmailMessage = "EmailTester.SUCESS"; } catch ( Exception e ) { logger.error( messages.getString( "EmailService.NOT_CONFIGURED" ), e ); sendEmailMessage = "EmailTester.FAIL"; } return sendEmailMessage; } /** * Validates and sets the email configuration file to the specified value. * * @param emailConfigFile * the email configuration file to use * @throws IllegalArgumentException * indicates that the provided value is invalid (the value is null or the parent folder does not exist) */ protected void setEmailConfigFile( final File emailConfigFile ) throws IllegalArgumentException { // Make sure the email config file provided isn't NULL, isn't a folder, or is specified to exist in a folder if ( emailConfigFile == null ) { throw new IllegalArgumentException( messages.getErrorString( "EmailService.ERROR_0001_INVALID_CONFIG_FILE_LOCATION", (Object) null ) ); } if ( emailConfigFile.exists() ) { if ( emailConfigFile.isDirectory() ) { throw new IllegalArgumentException( messages.getErrorString( "EmailService.ERROR_0001_INVALID_CONFIG_FILE_LOCATION", emailConfigFile.getAbsolutePath() ) ); } } else { final File parentFolder = emailConfigFile.getAbsoluteFile().getParentFile(); if ( !parentFolder.exists() || !parentFolder.isDirectory() ) { throw new IllegalArgumentException( messages.getErrorString( "EmailService.ERROR_0001_INVALID_CONFIG_FILE_LOCATION", emailConfigFile.getAbsolutePath() ) ); } } logger.debug( "Setting the email configuration file to [" + emailConfigFile.getAbsolutePath() + "]" ); logger.debug( "\temail config file exists = " + emailConfigFile.exists() ); this.emailConfigFile = emailConfigFile; } public boolean isValid() { try { EmailConfiguration c = new EmailConfigurationXml( emailConfigFile ); if ( !StringUtils.isEmpty( c.getSmtpHost() ) && !StringUtils.isEmpty( c.getSmtpProtocol() ) && !StringUtils.isEmpty( c.getDefaultFrom() ) ) { if ( c.isAuthenticate() ) { return !StringUtils.isEmpty( c.getUserId() ) && !StringUtils.isEmpty( c.getPassword() ); } return true; } } catch ( Exception e ) { //ignore } return false; } }