diff --git a/WHATSNEW b/WHATSNEW
index 1e6ba4fb9..7ca362571 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -32,7 +32,7 @@ Other changes:
--------------
* New tasks: ear, p4counter, record, cvspass, vsscheckin, vsscheckout,
- typedef, sleep
+ typedef, sleep, mimemail
* Ant now uses JAXP 1.1
diff --git a/build.xml b/build.xml
index 44aee2832..09254e4ed 100644
--- a/build.xml
+++ b/build.xml
@@ -89,7 +89,7 @@
Check to see what optional dependencies are available
===================================================================
-->
-
+
@@ -147,6 +147,18 @@
+
+
+
+
+
+
@@ -201,7 +213,9 @@
-
+
+
+
@@ -697,4 +711,13 @@
+
+
+
+
diff --git a/docs/manual/OptionalTasks/mimemail.html b/docs/manual/OptionalTasks/mimemail.html
new file mode 100644
index 000000000..2cc6e367c
--- /dev/null
+++ b/docs/manual/OptionalTasks/mimemail.html
@@ -0,0 +1,96 @@
+
+
+
+
+Ant User Manual
+
+
+
+
+
+Description
+Sends SMTP mail with MIME attachments. If no attachments
+are needed, use the built-in Mail
+task. JavaMail
+and Java
+Activation Framework are required for this task.
+Multiple files can be attached using FileSets.
+Parameters
+
+
+ Attribute |
+ Description |
+ Required |
+
+
+ message |
+ The message body |
+ No, but only one of of 'message' or
+ 'messageFile' may be specified. If not specified, a fileset must be
+ provided. |
+
+
+ messageFile |
+ A filename to read and used as the message body |
+
+
+ messageMimeType |
+ MIME type to use for 'message' or 'messageFile' when
+ attached. |
+ No, defaults to "text/plain" |
+
+
+ tolist |
+ Comma-separated list of To: recipients |
+ Yes, at least one of 'tolist', 'cclist',
+ or 'bcclist' must be specified. |
+
+
+ cclist |
+ Comma-separated list of CC: recipients |
+ |
+
+
+ bcclist |
+ Comma-separated list of BCC: recipients |
+ |
+
+
+ mailhost |
+ Host name of the mail server. |
+ No, default to "localhost" |
+
+
+ subject |
+ Email subject line. |
+ No |
+
+
+ from |
+ Email address of sender. |
+ Yes |
+
+
+ failonerror |
+ Stop the build process if an error occurs sending the
+ e-mail. |
+ No, default to "true" |
+
+
+Examples
+Send a single HTML file as the body of a message
+ <mimemail messageMimeType="text/html" messageFile="overview-summary.html"
+ tolist="you" subject="JUnit Test Results: ${TODAY}" from="me"/>
+Sends all files in a directory as attachments
+ <mimemail message="See attached files" tolist="you" subject="Attachments" from="me">
+ <fileset dir=".">
+ <include name="dist/*.*"/>
+ </fileset>
+ </mimemail>
+
+
Copyright © 2000,2001 Apache Software Foundation. All rights
+Reserved.
+
+
+
+
diff --git a/docs/manual/optionaltasklist.html b/docs/manual/optionaltasklist.html
index fb925458e..eeef161e2 100644
--- a/docs/manual/optionaltasklist.html
+++ b/docs/manual/optionaltasklist.html
@@ -26,6 +26,7 @@
Jlink
JUnit
JUnitReport
+MimeMail
MParse
Native2Ascii
NetRexxC
diff --git a/src/main/org/apache/tools/ant/taskdefs/Definer.java b/src/main/org/apache/tools/ant/taskdefs/Definer.java
index 86af92d20..0bbeb839b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Definer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Definer.java
@@ -96,7 +96,6 @@ public abstract class Definer extends Task {
throw new BuildException(msg);
}
try {
- ClassLoader loader = null;
AntClassLoader al = null;
if (classpath != null) {
al = new AntClassLoader(project, classpath);
@@ -107,9 +106,8 @@ public abstract class Definer extends Task {
// task we want to define will never be a Task but always
// be wrapped into a TaskAdapter.
al.addSystemPackageRoot("org.apache.tools.ant");
- loader = al;
- Class c = loader.loadClass(value);
+ Class c = al.loadClass(value);
AntClassLoader.initializeClass(c);
addDefinition(name, c);
} catch (ClassNotFoundException cnfe) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
new file mode 100644
index 000000000..251096ff0
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
@@ -0,0 +1,432 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 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 "The Jakarta Project", "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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.optional.net;
+
+
+// Standard SDK imports
+import java.util.Properties;
+import java.util.Vector;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+//imported for the mail api
+import javax.mail.Address;
+import javax.mail.Session;
+import javax.mail.Message;
+import javax.mail.BodyPart;
+import javax.mail.Multipart;
+import javax.mail.SendFailedException;
+import javax.mail.MessagingException;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.AddressException;
+
+//imported for data source and handler
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+
+// Ant imports
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.FileScanner;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+
+
+
+/**
+ * A task to send SMTP email. This version has near identical syntax to
+ * the SendEmail task, but is MIME aware. It also requires Sun's mail.jar and
+ * activation.jar to compile and execute, which puts it clearly into the
+ * very optional category.
+ *
+ * @author glenn_twiggs@bmc.com
+ * @author steve_l@iseran.com steve loughran
+ * @author erik@hatcher.net Erik Hatcher
+ * @author paulo.gaspar@krankikom.de Paulo Gaspar
+ * @created 01 May 2001
+ */
+public class MimeMail extends Task {
+ /**
+ * failure flag
+ */
+ private boolean failOnError = true;
+
+ /**
+ * sender
+ */
+ private String from = null;
+
+ /**
+ * host running SMTP
+ */
+ private String mailhost = "localhost";
+
+ /**
+ * any text
+ */
+ private String message = null;
+
+
+ /**
+ * message file (mutually exclusive from message)
+ */
+ private File messageFile = null;
+
+ /**
+ * TO recipients
+ */
+ private String toList = null;
+
+ /**
+ * CC (Carbon Copy) recipients
+ */
+ protected String ccList = null;
+
+ /**
+ * BCC (Blind Carbon Copy) recipients
+ */
+ protected String bccList = null;
+
+ /**
+ * subject field
+ */
+ private String subject = null;
+
+ /**
+ * file list
+ */
+ private Vector filesets = new Vector();
+
+ /**
+ * type of the text message, plaintext by default but text/html or
+ * text/xml is quite feasible
+ */
+ private String messageMimeType = "text/plain";
+
+ /**
+ * Creates new instance
+ */
+ public MimeMail() {
+ }
+
+
+ /**
+ * Sets the FailOnError attribute of the MimeMail object
+ *
+ * @param failOnError The new FailOnError value
+ */
+ public void setFailOnError(boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * Adds a set of files (nested fileset attribute).
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Sets the toList parameter of this build task.
+ *
+ * @param toList Comma-separated list of email recipient addreses.
+ */
+ public void setToList(String toList) {
+ this.toList = toList;
+ }
+
+ /**
+ * Sets the toList parameter of this build task.
+ *
+ * @param toList Comma-separated list of email recipient addreses.
+ */
+ public void setCcList(String ccList) {
+ this.ccList = ccList;
+ }
+
+ /**
+ * Sets the toList parameter of this build task.
+ *
+ * @param toList Comma-separated list of email recipient addreses.
+ */
+ public void setBccList(String bccList) {
+ this.bccList = bccList;
+ }
+
+
+ /**
+ * Sets the "from" parameter of this build task.
+ *
+ * @param from Email address of sender.
+ */
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+
+ /**
+ * Sets the mailhost parameter of this build task.
+ *
+ * @param mailhost Mail host name.
+ */
+ public void setMailhost(String mailhost) {
+ this.mailhost = mailhost;
+ }
+
+
+ /**
+ * Sets the message parameter of this build task.
+ *
+ * @param message Message body of this email.
+ */
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public void setMessageFile(File messageFile) {
+ this.messageFile = messageFile;
+ }
+
+
+ /**
+ * set type of the text message, plaintext by default but text/html
+ * or text/xml is quite feasible
+ *
+ * @param type The new MessageMimeType value
+ */
+ public void setMessageMimeType(String type) {
+ this.messageMimeType = type;
+ }
+
+ /**
+ * Sets the subject parameter of this build task.
+ *
+ * @param subject Subject of this email.
+ */
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+
+ /**
+ * verify parameters
+ *
+ * @throws BuildException if something is invalid
+ */
+ public void validate() {
+ if (from == null) {
+ throw new BuildException("Attribute \"from\" is required.");
+ }
+
+ if ((toList == null) && (ccList == null) && (bccList == null)) {
+ throw new BuildException("Attribute \"toList\", \"ccList\" or \"bccList\" is required.");
+ }
+
+ if (message == null && filesets.isEmpty() && messageFile == null) {
+ throw new BuildException("FileSet, \"message\", or \"messageFile\" is required.");
+ }
+
+ if (message != null && messageFile != null) {
+ throw new BuildException("Only one of \"message\" or \"messageFile\" may be specified.");
+ }
+ }
+
+
+ /**
+ * Executes this build task. throws org.apache.tools.ant.BuildException
+ * if there is an error during task execution.
+ *
+ * @exception BuildException Description of Exception
+ */
+ public void execute()
+ throws BuildException {
+ try {
+ validate();
+ doMail();
+ }
+ catch (Exception e) {
+ if (failOnError) {
+ throw new BuildException(e);
+ }
+ else {
+ String text = e.toString();
+ log(text, Project.MSG_ERR);
+ }
+ }
+ }
+
+
+ // helper method to add recipients
+ private static void addRecipients( MimeMessage msg,
+ Message.RecipientType recipType,
+ String addrUserName,
+ String addrList
+ ) throws MessagingException, BuildException {
+ if ((null == addrList) || (addrList.trim().length() <= 0))
+ return;
+
+ try {
+ InternetAddress[] addrArray = InternetAddress.parse(addrList);
+
+ if ((null == addrArray) || (0 == addrArray.length))
+ throw new BuildException("Empty " + addrUserName + " recipients list was specified");
+
+ msg.setRecipients(recipType, addrArray);
+ }
+ catch(AddressException ae) {
+ throw new BuildException("Invalid " + addrUserName + " recipient list");
+ }
+ }
+
+ /**
+ * here is where the mail is sent
+ *
+ * @exception MessagingException Description of Exception
+ * @exception AddressException Description of Exception
+ * @exception BuildException Description of Exception
+ */
+ public void doMail()
+ throws MessagingException, AddressException, BuildException {
+ Properties props = new Properties();
+ props.put("mail.smtp.host", mailhost);
+
+ //Aside, the JDK is clearly unaware of the scottish 'session', which
+ //involves excessive quantities of alcohol :-)
+ Session sesh = Session.getDefaultInstance(props, null);
+
+ //create the message
+ MimeMessage msg = new MimeMessage(sesh);
+
+ //set the sender
+ log("message sender: " + from, Project.MSG_VERBOSE);
+ msg.setFrom(new InternetAddress(from));
+
+ // add recipient lists
+ addRecipients(msg, Message.RecipientType.TO, "To", toList);
+ addRecipients(msg, Message.RecipientType.CC, "Cc", ccList);
+ addRecipients(msg, Message.RecipientType.BCC, "Bcc", bccList);
+
+ if (subject != null) {
+ log("subject: " + subject, Project.MSG_VERBOSE);
+ msg.setSubject(subject);
+ }
+
+ //now the complex bit; adding multiple mime objects. And guessing
+ //the file type
+ MimeMultipart attachments = new MimeMultipart();
+
+ //first a message
+ if (messageFile != null) {
+ int size = (int)messageFile.length();
+ byte data[] = new byte[size];
+
+ try {
+ FileInputStream inStream = new FileInputStream(messageFile);
+ inStream.read(data);
+ inStream.close();
+ message = new String(data);
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ if (message != null) {
+ MimeBodyPart textbody = new MimeBodyPart();
+ textbody.setContent(message, messageMimeType);
+ attachments.addBodyPart(textbody);
+ }
+
+ for (int i = 0; i < filesets.size(); i++)
+ {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ if (fs != null)
+ {
+ DirectoryScanner ds = fs.getDirectoryScanner(project);
+ String[] dsfiles = ds.getIncludedFiles();
+ File baseDir = ds.getBasedir();
+
+ for (int j = 0; j < dsfiles.length; j++)
+ {
+ File file = new File(baseDir, dsfiles[j]);
+ MimeBodyPart body;
+ body = new MimeBodyPart();
+ if (!file.exists() || !file.canRead()) {
+ throw new BuildException("File \"" + file.getAbsolutePath()
+ + "\" does not exist or is not readable.");
+ }
+ log("Attaching " + file.toString()+" - " +file.length()+" bytes",
+ Project.MSG_VERBOSE);
+ FileDataSource fileData = new FileDataSource(file);
+ DataHandler fileDataHandler = new DataHandler(fileData);
+ body.setDataHandler(fileDataHandler);
+ body.setFileName(file.getName());
+ attachments.addBodyPart(body);
+ } // for j
+ } // if (fs != null)
+ } // for i
+
+ msg.setContent(attachments);
+ log("sending email ");
+ Transport.send(msg);
+ }
+}
+
diff --git a/webpage/build.xml b/webpage/build.xml
index c98637480..942ed599e 100644
--- a/webpage/build.xml
+++ b/webpage/build.xml
@@ -1,9 +1,11 @@
-
-
-
+
+
+
+
+
@@ -32,36 +34,19 @@
+ templatePath="${templ.path}">
+ templatePath="${templ.path}">
-
-
-