001package votorola.g.mail; // Copyright 2007-2009, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. 002 003import com.sun.mail.smtp.*; 004import java.util.*; 005import java.util.logging.*; import votorola.g.logging.*; 006import javax.mail.*; 007import votorola.g.lang.*; 008import votorola.g.script.*; 009 010 011/** A sender of messages, with access to an SMTP mail transfer service. 012 */ 013public final @ThreadRestricted class MailSender 014{ 015 016 017 /** Constructs a MailSender. 018 */ 019 public MailSender( final SMTPTransportX.ConstructionContext cc ) 020 throws MisconfigurationException 021 { 022 authentication = cc.getAuthenticationMethod(); 023 serverName = cc.getServerName(); 024 serverPort = cc.getServerPort(); 025 026 final String enc = cc.getEncryptionMethod(); 027 if( enc == null ) protocolID = "smtp"; 028 else if( "ssl".equals( enc )) protocolID = "smtps"; 029 else throw new MisconfigurationException( "unrecognized encryption method: " + enc, cc.startupConfigurationFile() ); 030 } 031 032 033 034 // ------------------------------------------------------------------------------------ 035 036 037 /** Returns true if this mail sender is to run without actually sending any mail; 038 * while doing everything else, as far as possible. 039 * 040 * @see #setDryRun(boolean) 041 */ 042 public boolean isDryRun() { return dryRun; } 043 044 045 private boolean dryRun; 046 047 048 /** Sets whether the mail sender is to run without actually sending any mail. 049 * The default value is false; mail will actually be sent. 050 * 051 * @see #isDryRun() 052 */ 053 public final void setDryRun( boolean newDryRun ) { dryRun = newDryRun; } 054 055 056 057 /** Attempts to send a message. Returns any exception that occured, 058 * as a result of the attempt. 059 * 060 * @return any exception that occured; or null, if the attempt succeeded 061 */ 062 public Exception trySend( final Message message, Session session ) 063 { 064 try 065 { 066 message.setSentDate( new Date() ); 067 logger.fine( "sending From=" + MessageX.getFirstFrom(message) + ", To[0]=" + MessageX.getFirstRecipient(message,Message.RecipientType.TO) ); 068 069 final SMTPTransport transport = (SMTPTransport)session.getTransport( protocolID ); 070 if( dryRun ) return null; 071 072 try 073 { 074 if( authentication == null ) 075 { 076 transport.connect( serverName, serverPort, null, null ); 077 } 078 else 079 { 080 transport.connect( serverName, serverPort, 081 authentication.name(), authentication.password() ); 082 } 083 transport.sendMessage( message, message.getAllRecipients() ); 084 } 085 finally 086 { 087 final String s = transport.getLastServerResponse(); 088 final StringBuilder b = new StringBuilder( s == null? "(no response)": s ); 089 StringBuilderX.trim( b ); 090 logger.fine( "server responds: " + b.toString() ); 091 transport.close(); 092 } 093 } 094 catch( Exception x ) { return x; } 095 return null; 096 } 097 098 099 100//// P r i v a t e /////////////////////////////////////////////////////////////////////// 101 102 103 private final SMTPTransportX.SimpleAuthentication authentication; 104 105 106 107 private static final Logger logger = LoggerX.i( MailSender.class ); 108 109 110 111 private final String protocolID; 112 113 114 115 private final String serverName; 116 117 118 119 private final int serverPort; 120 121 122 123}