git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@704528 13f79535-47bb-0310-9956-ffa450edef68master
@@ -425,6 +425,10 @@ Other changes: | |||
used by MailLogger. | |||
Bugzilla Report 27211. | |||
* a new attribute of <mail> allows the task to succeed if it can | |||
reach at least one given recipient. | |||
Bugzilla Report 36446. | |||
Changes from Ant 1.7.0 TO Ant 1.7.1 | |||
============================================= | |||
@@ -172,6 +172,13 @@ | |||
<td valign="top">Email subject line.</td> | |||
<td align="center" valign="top">No</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">ignoreInvalidRecipients</td> | |||
<td valign="top">Boolean. Whether the task should try to send | |||
the message to as many recipients as possible and should only | |||
fail if neither is reachable. <em>Since Ant 1.8.0</em>.</td> | |||
<td align="center" valign="top">No, default is false</td> | |||
</tr> | |||
</table> | |||
<h3>Note regarding the attributes containing email addresses</h3> | |||
@@ -103,6 +103,9 @@ public class EmailTask extends Task { | |||
/** indicate if the user wishes SSL-TLS */ | |||
private boolean ssl = false; | |||
/** ignore invalid recipients? */ | |||
private boolean ignoreInvalidRecipients = false; | |||
/** | |||
* Set the user for SMTP auth; this requires JavaMail. | |||
* @param user the String username. | |||
@@ -402,6 +405,19 @@ public class EmailTask extends Task { | |||
return includeFileNames; | |||
} | |||
/** | |||
* Whether invalid recipients should be ignored (but a warning | |||
* will be logged) instead of making the task fail. | |||
* | |||
* <p>Even with this property set to true the task will still fail | |||
* if the mail couldn't be sent to any recipient at all.</p> | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public void setIgnoreInvalidRecipients(boolean b) { | |||
ignoreInvalidRecipients = b; | |||
} | |||
/** | |||
* Send an email. | |||
*/ | |||
@@ -532,6 +548,7 @@ public class EmailTask extends Task { | |||
mailer.setTask(this); | |||
mailer.setIncludeFileNames(includeFileNames); | |||
mailer.setHeaders(headers); | |||
mailer.setIgnoreInvalidRecipients(ignoreInvalidRecipients); | |||
// send the email | |||
mailer.send(); | |||
@@ -48,6 +48,7 @@ public abstract class Mailer { | |||
protected boolean includeFileNames = false; | |||
protected Vector headers = null; | |||
// CheckStyle:VisibilityModifier ON | |||
private boolean ignoreInvalidRecipients = false; | |||
/** | |||
* Set the mail server. | |||
@@ -205,6 +206,28 @@ public abstract class Mailer { | |||
public abstract void send() | |||
throws BuildException; | |||
/** | |||
* Whether invalid recipients should be ignored (but a warning | |||
* will be logged) instead of making the task fail. | |||
* | |||
* <p>Even with this property set to true the task will still fail | |||
* if the mail couldn't be sent to any recipient at all.</p> | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public void setIgnoreInvalidRecipients(boolean b) { | |||
ignoreInvalidRecipients = b; | |||
} | |||
/** | |||
* Whether invalid recipients should be ignored. | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
protected boolean shouldIgnoreInvalidRecipients() { | |||
return ignoreInvalidRecipients; | |||
} | |||
/** | |||
* Return the current Date in a format suitable for a SMTP date | |||
* header. | |||
@@ -38,19 +38,22 @@ import java.security.Security; | |||
import javax.activation.DataHandler; | |||
import javax.activation.FileDataSource; | |||
import javax.mail.Message; | |||
import javax.mail.Session; | |||
import javax.mail.Transport; | |||
import javax.mail.Authenticator; | |||
import javax.mail.Address; | |||
import javax.mail.Message; | |||
import javax.mail.MessagingException; | |||
import javax.mail.PasswordAuthentication; | |||
import javax.mail.internet.MimeMessage; | |||
import javax.mail.SendFailedException; | |||
import javax.mail.Session; | |||
import javax.mail.Transport; | |||
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; | |||
import javax.mail.internet.InternetAddress; | |||
import javax.mail.internet.AddressException; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
/** | |||
* Uses the JavaMail classes to send Mime format email. | |||
@@ -60,6 +63,9 @@ import org.apache.tools.ant.BuildException; | |||
public class MimeMailer extends Mailer { | |||
private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; | |||
private static final String GENERIC_ERROR = | |||
"Problem while sending mime mail:"; | |||
/** Default character set */ | |||
private static final String DEFAULT_CHARSET | |||
= System.getProperty("file.encoding"); | |||
@@ -237,11 +243,36 @@ public class MimeMailer extends Mailer { | |||
attachments.addBodyPart(body); | |||
} | |||
msg.setContent(attachments); | |||
Transport.send(msg); | |||
try { | |||
Transport.send(msg); | |||
} catch (SendFailedException sfe) { | |||
if (!shouldIgnoreInvalidRecipients()) { | |||
throw new BuildException(GENERIC_ERROR, sfe); | |||
} else if (sfe.getValidSentAddresses() == null | |||
|| sfe.getValidSentAddresses().length == 0) { | |||
throw new BuildException("Couldn't reach any recipient", | |||
sfe); | |||
} else { | |||
Address[] invalid = sfe.getInvalidAddresses(); | |||
if (invalid == null) { | |||
invalid = new Address[0]; | |||
} | |||
for (int i = 0; i < invalid.length; i++) { | |||
didntReach(invalid[i], "invalid", sfe); | |||
} | |||
Address[] validUnsent = sfe.getValidUnsentAddresses(); | |||
if (validUnsent == null) { | |||
validUnsent = new Address[0]; | |||
} | |||
for (int i = 0; i < validUnsent.length; i++) { | |||
didntReach(validUnsent[i], "valid", sfe); | |||
} | |||
} | |||
} | |||
} catch (MessagingException e) { | |||
throw new BuildException("Problem while sending mime mail:", e); | |||
throw new BuildException(GENERIC_ERROR, e); | |||
} catch (IOException e) { | |||
throw new BuildException("Problem while sending mime mail:", e); | |||
throw new BuildException(GENERIC_ERROR, e); | |||
} | |||
} | |||
@@ -274,6 +305,17 @@ public class MimeMailer extends Mailer { | |||
return token.nextToken(); | |||
} | |||
private void didntReach(Address addr, String category, | |||
MessagingException ex) { | |||
String msg = "Failed to send mail to " + category + " address " | |||
+ addr + " because of " + ex.getMessage(); | |||
if (task != null) { | |||
task.log(msg, Project.MSG_WARN); | |||
} else { | |||
System.err.println(msg); | |||
} | |||
} | |||
static class SimpleAuthenticator extends Authenticator { | |||
private String user = null; | |||
private String password = null; | |||
@@ -24,6 +24,7 @@ import java.io.IOException; | |||
import java.io.PrintStream; | |||
import java.util.Enumeration; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.mail.MailMessage; | |||
/** | |||
@@ -44,6 +45,7 @@ class PlainMailer extends Mailer { | |||
mailMessage.from(from.toString()); | |||
Enumeration e; | |||
boolean atLeastOneRcptReached = false; | |||
e = replyToList.elements(); | |||
while (e.hasMoreElements()) { | |||
@@ -51,15 +53,36 @@ class PlainMailer extends Mailer { | |||
} | |||
e = toList.elements(); | |||
while (e.hasMoreElements()) { | |||
mailMessage.to(e.nextElement().toString()); | |||
String to = e.nextElement().toString(); | |||
try { | |||
mailMessage.to(to); | |||
atLeastOneRcptReached = true; | |||
} catch (IOException ex) { | |||
badRecipient(to, ex); | |||
} | |||
} | |||
e = ccList.elements(); | |||
while (e.hasMoreElements()) { | |||
mailMessage.cc(e.nextElement().toString()); | |||
String to = e.nextElement().toString(); | |||
try { | |||
mailMessage.cc(to); | |||
atLeastOneRcptReached = true; | |||
} catch (IOException ex) { | |||
badRecipient(to, ex); | |||
} | |||
} | |||
e = bccList.elements(); | |||
while (e.hasMoreElements()) { | |||
mailMessage.bcc(e.nextElement().toString()); | |||
String to = e.nextElement().toString(); | |||
try { | |||
mailMessage.bcc(to); | |||
atLeastOneRcptReached = true; | |||
} catch (IOException ex) { | |||
badRecipient(to, ex); | |||
} | |||
} | |||
if (!atLeastOneRcptReached) { | |||
throw new BuildException("Couldn't reach any recipient"); | |||
} | |||
if (subject != null) { | |||
mailMessage.setSubject(subject); | |||
@@ -135,5 +158,19 @@ class PlainMailer extends Mailer { | |||
finstr.close(); | |||
} | |||
} | |||
private void badRecipient(String rcpt, IOException reason) { | |||
String msg = "Failed to send mail to " + rcpt; | |||
if (shouldIgnoreInvalidRecipients()) { | |||
msg += " because of :" + reason.getMessage(); | |||
if (task != null) { | |||
task.log(msg, Project.MSG_WARN); | |||
} else { | |||
System.err.println(msg); | |||
} | |||
} else { | |||
throw new BuildException(msg, reason); | |||
} | |||
} | |||
} | |||