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); | |||
| } | |||
| } | |||
| } | |||