and MailLogger. PR: 5969 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274624 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -301,6 +301,12 @@ Other changes: | |||||
| * <mail> has a new attribute encoding. Bugzilla Report 15434. | * <mail> has a new attribute encoding. Bugzilla Report 15434. | ||||
| * <mail> has new attributes user and password for SMTP auth. | |||||
| maillogger can also use this. | |||||
| The implementation only with JavaMail (encoding="MIME"). | |||||
| Implementation with plain mail remains to do. | |||||
| Bugzilla Report 5969. | |||||
| * <zipfileset> can now be defined in the main body of a project | * <zipfileset> can now be defined in the main body of a project | ||||
| and referred to with refid="xyz". Bugzilla Report 17007. | and referred to with refid="xyz". Bugzilla Report 17007. | ||||
| @@ -0,0 +1,15 @@ | |||||
| <?xml version="1.0"?> | |||||
| <project name="mail-test" basedir="." default="test1"> | |||||
| <target name="test1"> | |||||
| <!-- this test is supposed to bring a build exception because user and password is not allowed with plain encoding --> | |||||
| <mail host="localhost" port="25" from="joe@abc.com" to="laura@xyz.com" subject="hello" encoding="plain" user="joe" password="secret"> | |||||
| <message> | |||||
| Hi Laura, how are you doing ? | |||||
| </message> | |||||
| </mail> | |||||
| </target> | |||||
| </project> | |||||
| @@ -57,13 +57,14 @@ import java.io.FileInputStream; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.io.PrintStream; | import java.io.PrintStream; | ||||
| import java.util.Enumeration; | |||||
| import java.util.Hashtable; | |||||
| import java.util.Properties; | |||||
| import java.util.StringTokenizer; | |||||
| import java.util.*; | |||||
| import org.apache.tools.ant.BuildEvent; | import org.apache.tools.ant.BuildEvent; | ||||
| import org.apache.tools.ant.DefaultLogger; | import org.apache.tools.ant.DefaultLogger; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.taskdefs.email.MimeMailer; | |||||
| import org.apache.tools.ant.taskdefs.email.EmailAddress; | |||||
| import org.apache.tools.ant.taskdefs.email.Message; | |||||
| import org.apache.tools.ant.util.DateUtils; | import org.apache.tools.ant.util.DateUtils; | ||||
| import org.apache.tools.ant.util.StringUtils; | import org.apache.tools.ant.util.StringUtils; | ||||
| import org.apache.tools.mail.MailMessage; | import org.apache.tools.mail.MailMessage; | ||||
| @@ -96,6 +97,8 @@ import org.apache.tools.mail.MailMessage; | |||||
| * | * | ||||
| * @author Erik Hatcher | * @author Erik Hatcher | ||||
| * <a href="mailto:ehatcher@apache.org">ehatcher@apache.org</a> | * <a href="mailto:ehatcher@apache.org">ehatcher@apache.org</a> | ||||
| * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a> | |||||
| * | |||||
| */ | */ | ||||
| public class MailLogger extends DefaultLogger { | public class MailLogger extends DefaultLogger { | ||||
| /** Buffer in which the message is constructed prior to sending */ | /** Buffer in which the message is constructed prior to sending */ | ||||
| @@ -152,13 +155,19 @@ public class MailLogger extends DefaultLogger { | |||||
| String mailhost = getValue(properties, "mailhost", "localhost"); | String mailhost = getValue(properties, "mailhost", "localhost"); | ||||
| int port = Integer.parseInt(getValue(properties,"port",String.valueOf(MailMessage.DEFAULT_PORT))); | int port = Integer.parseInt(getValue(properties,"port",String.valueOf(MailMessage.DEFAULT_PORT))); | ||||
| String user = getValue(properties, "user", null); | |||||
| String password = getValue(properties, "password", null); | |||||
| String from = getValue(properties, "from", null); | String from = getValue(properties, "from", null); | ||||
| String replytoList = getValue(properties,"replyto",""); | String replytoList = getValue(properties,"replyto",""); | ||||
| String toList = getValue(properties, prefix + ".to", null); | String toList = getValue(properties, prefix + ".to", null); | ||||
| String subject = getValue(properties, prefix + ".subject", | String subject = getValue(properties, prefix + ".subject", | ||||
| (success) ? "Build Success" : "Build Failure"); | (success) ? "Build Success" : "Build Failure"); | ||||
| sendMail(mailhost, port, from, replytoList, toList, subject, buffer.substring(0)); | |||||
| if (user==null && password==null) { | |||||
| sendMail(mailhost, port, from, replytoList, toList, subject, buffer.substring(0)); | |||||
| } | |||||
| else { | |||||
| sendMimeMail(event.getProject(), mailhost, port, user, password, from, replytoList, toList, subject, buffer.substring(0)); | |||||
| } | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| System.out.println("MailLogger failed to send e-mail!"); | System.out.println("MailLogger failed to send e-mail!"); | ||||
| e.printStackTrace(System.err); | e.printStackTrace(System.err); | ||||
| @@ -207,7 +216,6 @@ public class MailLogger extends DefaultLogger { | |||||
| /** | /** | ||||
| * Send the mail | * Send the mail | ||||
| * | |||||
| * @param mailhost mail server | * @param mailhost mail server | ||||
| * @param port mail server port number | * @param port mail server port number | ||||
| * @param from from address | * @param from from address | ||||
| @@ -241,6 +249,50 @@ public class MailLogger extends DefaultLogger { | |||||
| mailMessage.sendAndClose(); | mailMessage.sendAndClose(); | ||||
| } | } | ||||
| /** | |||||
| * Send the mail (MimeMail) | |||||
| * @param project current ant project | |||||
| * @param host mail server | |||||
| * @param port mail server port number | |||||
| * @param user user name for SMTP auth | |||||
| * @param password password for SMTP auth | |||||
| * @param from from address | |||||
| * @param replyToString comma-separated replyto list | |||||
| * @param toString comma-separated recipient list | |||||
| * @param subject mail subject | |||||
| * @param message mail body | |||||
| * @exception IOException thrown if sending message fails | |||||
| */ | |||||
| private void sendMimeMail(Project project, String host, int port, String user, String password, String from, String replyToString, String toString, | |||||
| String subject, String message) throws IOException { | |||||
| // convert the replyTo string into a vector of emailaddresses | |||||
| Vector replyToList = vectorizeEmailAddresses(replyToString); | |||||
| MimeMailer mailer=new MimeMailer(); | |||||
| mailer.setHost(host); | |||||
| mailer.setPort(port); | |||||
| mailer.setUser(user); | |||||
| mailer.setPassword(password); | |||||
| Message mymessage = new Message(message); | |||||
| mymessage.setProject(project); | |||||
| mailer.setMessage(mymessage); | |||||
| mailer.setFrom(new EmailAddress(from)); | |||||
| mailer.setReplyToList(replyToList); | |||||
| Vector toList = vectorizeEmailAddresses(toString); | |||||
| mailer.setToList(toList); | |||||
| mailer.setCcList(new Vector()); | |||||
| mailer.setBccList(new Vector()); | |||||
| mailer.setFiles(new Vector()); | |||||
| mailer.setSubject(subject); | |||||
| mailer.send(); | |||||
| } | |||||
| private Vector vectorizeEmailAddresses(String listString) { | |||||
| Vector emailList = new Vector(); | |||||
| StringTokenizer tokens = new StringTokenizer(listString, ","); | |||||
| while (tokens.hasMoreTokens()) { | |||||
| emailList.addElement(new EmailAddress(tokens.nextToken())); | |||||
| } | |||||
| return emailList; | |||||
| } | |||||
| } | } | ||||
| @@ -142,7 +142,28 @@ public class EmailTask | |||||
| private boolean debugonly=false; | private boolean debugonly=false; | ||||
| /** a location where to print the email message */ | /** a location where to print the email message */ | ||||
| private File debugoutput; | private File debugoutput; | ||||
| /** User for SMTP auth */ | |||||
| private String user=null; | |||||
| /** Password for SMTP auth */ | |||||
| private String password=null; | |||||
| /** | |||||
| * sets the user for SMTP auth; this requires JavaMail | |||||
| * @param user | |||||
| * @since ant 1.6 | |||||
| */ | |||||
| public void setUser(String user) { | |||||
| this.user = user; | |||||
| } | |||||
| /** | |||||
| * sets the password for SMTP auth; this requires JavaMail | |||||
| * @param password | |||||
| * @since ant 1.6 | |||||
| */ | |||||
| public void setPassword(String password) { | |||||
| this.password = password; | |||||
| } | |||||
| /** | /** | ||||
| * Allows the build writer to choose the preferred encoding method | * Allows the build writer to choose the preferred encoding method | ||||
| @@ -431,7 +452,6 @@ public class EmailTask | |||||
| // prepare for the auto select mechanism | // prepare for the auto select mechanism | ||||
| boolean autoFound = false; | boolean autoFound = false; | ||||
| // try MIME format | // try MIME format | ||||
| if (encoding.equals(MIME) | if (encoding.equals(MIME) | ||||
| || (encoding.equals(AUTO) && !autoFound)) { | || (encoding.equals(AUTO) && !autoFound)) { | ||||
| @@ -445,6 +465,10 @@ public class EmailTask | |||||
| log("Failed to initialise MIME mail: "+e.getMessage(),Project.MSG_WARN); | log("Failed to initialise MIME mail: "+e.getMessage(),Project.MSG_WARN); | ||||
| } | } | ||||
| } | } | ||||
| // SMTP auth only allowed with MIME mail | |||||
| if (autoFound==false && ((user !=null) || (password != null)) && (encoding.equals(UU) || encoding.equals(PLAIN))) { | |||||
| throw new BuildException("SMTP auth only possible with MIME mail"); | |||||
| } | |||||
| // try UU format | // try UU format | ||||
| if (encoding.equals(UU) | if (encoding.equals(UU) | ||||
| @@ -538,6 +562,8 @@ public class EmailTask | |||||
| // pass the params to the mailer | // pass the params to the mailer | ||||
| mailer.setHost(host); | mailer.setHost(host); | ||||
| mailer.setPort(port); | mailer.setPort(port); | ||||
| mailer.setUser(user); | |||||
| mailer.setPassword(password); | |||||
| mailer.setMessage(message); | mailer.setMessage(message); | ||||
| mailer.setFrom(from); | mailer.setFrom(from); | ||||
| mailer.setReplyToList(replyToList); | mailer.setReplyToList(replyToList); | ||||
| @@ -67,6 +67,8 @@ import org.apache.tools.ant.util.DateUtils; | |||||
| abstract class Mailer { | abstract class Mailer { | ||||
| protected String host = null; | protected String host = null; | ||||
| protected int port = -1; | protected int port = -1; | ||||
| protected String user = null; | |||||
| protected String password = null; | |||||
| protected Message message; | protected Message message; | ||||
| protected EmailAddress from; | protected EmailAddress from; | ||||
| protected Vector replyToList = null; | protected Vector replyToList = null; | ||||
| @@ -97,6 +99,23 @@ abstract class Mailer { | |||||
| this.port = port; | this.port = port; | ||||
| } | } | ||||
| /** | |||||
| * Sets the user for smtp auth | |||||
| * | |||||
| * @param user | |||||
| */ | |||||
| public void setUser(String user) { | |||||
| this.user = user; | |||||
| } | |||||
| /** | |||||
| * Sets the password for smtp auth | |||||
| * | |||||
| * @param password | |||||
| */ | |||||
| public void setPassword(String password) { | |||||
| this.password = password; | |||||
| } | |||||
| /** | /** | ||||
| * Sets the message | * Sets the message | ||||
| @@ -70,10 +70,8 @@ import java.util.Vector; | |||||
| import javax.activation.DataHandler; | import javax.activation.DataHandler; | ||||
| import javax.activation.FileDataSource; | import javax.activation.FileDataSource; | ||||
| import javax.mail.*; | |||||
| import javax.mail.Message; | import javax.mail.Message; | ||||
| import javax.mail.MessagingException; | |||||
| import javax.mail.Session; | |||||
| import javax.mail.Transport; | |||||
| import javax.mail.internet.AddressException; | import javax.mail.internet.AddressException; | ||||
| import javax.mail.internet.InternetAddress; | import javax.mail.internet.InternetAddress; | ||||
| import javax.mail.internet.MimeBodyPart; | import javax.mail.internet.MimeBodyPart; | ||||
| @@ -89,7 +87,7 @@ import org.apache.tools.ant.BuildException; | |||||
| * @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a> | * @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a> | ||||
| * @since Ant 1.5 | * @since Ant 1.5 | ||||
| */ | */ | ||||
| class MimeMailer extends Mailer { | |||||
| public class MimeMailer extends Mailer { | |||||
| // Default character set | // Default character set | ||||
| private static final String defaultCharset = System.getProperty("file.encoding"); | private static final String defaultCharset = System.getProperty("file.encoding"); | ||||
| @@ -157,7 +155,16 @@ class MimeMailer extends Mailer { | |||||
| // Aside, the JDK is clearly unaware of the scottish | // Aside, the JDK is clearly unaware of the scottish | ||||
| // 'session', which //involves excessive quantities of | // 'session', which //involves excessive quantities of | ||||
| // alcohol :-) | // alcohol :-) | ||||
| Session sesh = Session.getDefaultInstance(props, null); | |||||
| Session sesh; | |||||
| Authenticator auth; | |||||
| if (user==null && password == null) { | |||||
| sesh = Session.getDefaultInstance(props, null); | |||||
| } | |||||
| else { | |||||
| props.put("mail.smtp.auth", "true"); | |||||
| auth = new SimpleAuthenticator(user,password); | |||||
| sesh = Session.getInstance(props,auth); | |||||
| } | |||||
| //create the message | //create the message | ||||
| MimeMessage msg = new MimeMessage(sesh); | MimeMessage msg = new MimeMessage(sesh); | ||||
| @@ -260,6 +267,7 @@ class MimeMailer extends Mailer { | |||||
| } | } | ||||
| return addrs; | return addrs; | ||||
| } | } | ||||
| private String parseCharSetFromMimeType(String type){ | private String parseCharSetFromMimeType(String type){ | ||||
| @@ -271,5 +279,18 @@ class MimeMailer extends Mailer { | |||||
| token.nextToken();// Skip 'charset=' | token.nextToken();// Skip 'charset=' | ||||
| return token.nextToken(); | return token.nextToken(); | ||||
| } | } | ||||
| } | |||||
| static class SimpleAuthenticator extends Authenticator { | |||||
| private String user=null; | |||||
| private String password=null; | |||||
| public SimpleAuthenticator(String user, String password) { | |||||
| this.user=user; | |||||
| this.password=password; | |||||
| } | |||||
| public PasswordAuthentication getPasswordAuthentication() { | |||||
| return new PasswordAuthentication(user, password); | |||||
| } | |||||
| }} | |||||
| @@ -0,0 +1,80 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2003 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "Ant" and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| import java.io.File; | |||||
| import org.apache.tools.ant.BuildFileTest; | |||||
| /** | |||||
| * TODO : develop these testcases - the email task needs to have attributes allowing | |||||
| * to simulate sending mail and to catch the output in text files or streams | |||||
| * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a> | |||||
| */ | |||||
| public class EmailTaskTest extends BuildFileTest { | |||||
| public EmailTaskTest(String name) { | |||||
| super(name); | |||||
| } | |||||
| public void setUp() { | |||||
| configureProject("src/etc/testcases/taskdefs/mail.xml"); | |||||
| } | |||||
| public void test1() { | |||||
| expectBuildException("test1", "SMTP auth only possible with MIME mail"); | |||||
| } | |||||
| } | |||||