Browse Source

add international support for mailtask - bug report 15434

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274480 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 22 years ago
parent
commit
416d46165b
4 changed files with 199 additions and 15 deletions
  1. +29
    -0
      docs/manual/CoreTasks/mail.html
  2. +38
    -2
      src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java
  3. +29
    -3
      src/main/org/apache/tools/ant/taskdefs/email/Message.java
  4. +103
    -10
      src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java

+ 29
- 0
docs/manual/CoreTasks/mail.html View File

@@ -100,6 +100,13 @@ Library Dependencies</a> for more information.
<code>auto</code>. The default value is <code>auto</code>.</td> <code>auto</code>. The default value is <code>auto</code>.</td>
<td align="center" valign="top">No</td> <td align="center" valign="top">No</td>
</tr> </tr>
<tr>
<td valign="top">charset</td>
<td valign="top">Character set of the email.<br>
You can also set the charset in the message nested element.<br>
These options are mutually exclusive.</td>
<td align="center" valign="top">No</td>
</tr>
<tr> <tr>
<td valign="top">subject</td> <td valign="top">subject</td>
<td valign="top">Email subject line.</td> <td valign="top">Email subject line.</td>
@@ -151,6 +158,13 @@ attributes:</p>
<td valign="top">The content type to use for the message.</td> <td valign="top">The content type to use for the message.</td>
<td align="center" valign="top">No</td> <td align="center" valign="top">No</td>
</tr> </tr>
<tr>
<td valign="top">charset</td>
<td valign="top">Character set of the message<br>
You can also set the charset as attribute of the enclosing mail task.<br>
These options are mutually exclusive.</td>
<td align="center" valign="top">No</td>
</tr>
</table> </table>


<p>If the <code>src</code> attribute is not specified, then text can be added <p>If the <code>src</code> attribute is not specified, then text can be added
@@ -187,6 +201,21 @@ the <code>&lt;message&gt;</code> element.</p>
task will attempt to use JavaMail and fall back to UU encoding or no encoding in task will attempt to use JavaMail and fall back to UU encoding or no encoding in
that order depending on what support classes are available. <code>${buildname}</code> that order depending on what support classes are available. <code>${buildname}</code>
will be replaced with the <code>buildname</code> property's value.</p> will be replaced with the <code>buildname</code> property's value.</p>

<blockquote><pre>
&lt;property name=&quot;line2&quot; value=&quot;some_international_message&quot;/&gt;
&lt;echo message=&quot;${line2}&quot;/&gt;

&lt;mail mailhost=&quot;somehost@xyz.com&quot; mailport=&quot;25&quot; subject=&quot;Test build&quot; charset=&quot;utf-8&quot;&gt;
&lt;from address=&quot;me@myist.com&quot;/&gt;
&lt;to address=&quot;all@xyz.com&quot; /&gt;
&lt;message&gt;some international text:${line2}&lt;/message&gt;
&lt;/mail&gt;
</pre></blockquote>

<p>Sends an eMail from <i>me@myisp.com</i> to <i>all@xyz.com</i> with a subject of
<i>Test Build</i>, the message body being coded in UTF-8

<hr> <hr>
<p align="center">Copyright &copy; 2000-2003 Apache Software Foundation. All rights <p align="center">Copyright &copy; 2000-2003 Apache Software Foundation. All rights
Reserved.</p> Reserved.</p>


+ 38
- 2
src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java View File

@@ -1,7 +1,7 @@
/* /*
* The Apache Software License, Version 1.1 * The Apache Software License, Version 1.1
* *
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights
* reserved. * reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -76,6 +76,7 @@ import org.apache.tools.ant.types.FileSet;
* @author ehatcher@apache.org Erik Hatcher * @author ehatcher@apache.org Erik Hatcher
* @author paulo.gaspar@krankikom.de Paulo Gaspar * @author paulo.gaspar@krankikom.de Paulo Gaspar
* @author roxspring@imapmail.org Rob Oxspring * @author roxspring@imapmail.org Rob Oxspring
* @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a>
* @since Ant 1.5 * @since Ant 1.5
* @ant.task name="mail" category="network" * @ant.task name="mail" category="network"
*/ */
@@ -132,6 +133,8 @@ public class EmailTask
/** file list */ /** file list */
private Vector files = new Vector(); private Vector files = new Vector();
private Vector filesets = new Vector(); private Vector filesets = new Vector();
/** Character set for MimeMailer*/
private String charset=null;




/** /**
@@ -410,7 +413,7 @@ public class EmailTask
autoFound = true; autoFound = true;
log("Using MIME mail", Project.MSG_VERBOSE); log("Using MIME mail", Project.MSG_VERBOSE);
} catch (Throwable e) { } catch (Throwable e) {
log("Failed to initialise MIME mail", Project.MSG_WARN);
log("Failed to initialise MIME mail: "+e.getMessage(),Project.MSG_WARN);
} }
} }


@@ -468,6 +471,15 @@ public class EmailTask
message.setMimeType(messageMimeType); message.setMimeType(messageMimeType);
} }
} }
// set the character set if not done already (and required)
if (charset != null) {
if (message.getCharset()!=null) {
throw new BuildException("The charset can only be "
+ "specified in one location");
} else {
message.setCharset(charset);
}
}


// identify which files should be attached // identify which files should be attached
Enumeration e = filesets.elements(); Enumeration e = filesets.elements();
@@ -519,10 +531,34 @@ public class EmailTask
if (failOnError) { if (failOnError) {
throw e; throw e;
} }
}
catch(Exception e){
log("Failed to send email", Project.MSG_WARN);
if (failOnError) {
throw new BuildException(e);
}
} finally { } finally {
message = savedMessage; message = savedMessage;
files = savedFiles; files = savedFiles;
} }
} }
/**
* Sets the character set of mail message.
* Will be ignored if mimeType contains ....; Charset=... substring or
* encoding is not a <code>mime</code>
* @since Ant 1.6
*/
public void setCharset(String charset) {
this.charset = charset;
}
/**
* Returns the character set of mail message.
*
* @return Charset of mail message.
* @since Ant 1.6
*/
public String getCharset() {
return charset;
}
} }



+ 29
- 3
src/main/org/apache/tools/ant/taskdefs/email/Message.java View File

@@ -57,13 +57,17 @@ import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter;

import org.apache.tools.ant.ProjectComponent; import org.apache.tools.ant.ProjectComponent;


/** /**
* Class representing an email message. * Class representing an email message.
* *
* @author roxspring@yahoo.com Rob Oxspring * @author roxspring@yahoo.com Rob Oxspring
* @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a>
* @since Ant 1.5 * @since Ant 1.5
*/ */
public class Message extends ProjectComponent { public class Message extends ProjectComponent {
@@ -71,7 +75,7 @@ public class Message extends ProjectComponent {
private StringBuffer buffer = new StringBuffer(); private StringBuffer buffer = new StringBuffer();
private String mimeType = "text/plain"; private String mimeType = "text/plain";
private boolean specified = false; private boolean specified = false;
private String charset=null;


/** Creates a new empty message */ /** Creates a new empty message */
public Message() { public Message() {
@@ -145,8 +149,13 @@ public class Message extends ProjectComponent {
* @param out The print stream to write to * @param out The print stream to write to
* @throws IOException if an error occurs * @throws IOException if an error occurs
*/ */
public void print(PrintStream out)
public void print(PrintStream ps)
throws IOException { throws IOException {
// We need character encoding aware printing here.
// So, using PrintWriter over OutputStreamWriter instead of PrintStream
PrintWriter out = charset!=null?
new PrintWriter(new OutputStreamWriter(ps,charset)):
new PrintWriter(ps);
if (messageSource != null) { if (messageSource != null) {
// Read message from a file // Read message from a file
FileReader freader = new FileReader(messageSource); FileReader freader = new FileReader(messageSource);
@@ -154,7 +163,6 @@ public class Message extends ProjectComponent {
try { try {
BufferedReader in = new BufferedReader(freader); BufferedReader in = new BufferedReader(freader);
String line = null; String line = null;

while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
out.println(getProject().replaceProperties(line)); out.println(getProject().replaceProperties(line));
} }
@@ -164,6 +172,7 @@ public class Message extends ProjectComponent {
} else { } else {
out.println(getProject().replaceProperties(buffer.substring(0))); out.println(getProject().replaceProperties(buffer.substring(0)));
} }
out.flush();
} }




@@ -175,5 +184,22 @@ public class Message extends ProjectComponent {
public boolean isMimeTypeSpecified() { public boolean isMimeTypeSpecified() {
return specified; return specified;
} }
/**
* Sets the character set of mail message.
* Will be ignored if mimeType contains ....; Charset=... substring.
* @since Ant 1.6
*/
public void setCharset(String charset) {
this.charset = charset;
}
/**
* Returns the charset of mail message.
*
* @return Charset of mail message.
* @since Ant 1.6
*/
public String getCharset() {
return charset;
}
} }



+ 103
- 10
src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java View File

@@ -1,7 +1,7 @@
/* /*
* The Apache Software License, Version 1.1 * The Apache Software License, Version 1.1
* *
* Copyright (c) 2002 The Apache Software Foundation. All rights
* Copyright (c) 2002-2003 The Apache Software Foundation. All rights
* reserved. * reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -53,16 +53,23 @@
*/ */
package org.apache.tools.ant.taskdefs.email; package org.apache.tools.ant.taskdefs.email;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;

import java.util.Enumeration; import java.util.Enumeration;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector; import java.util.Vector;

import javax.activation.DataHandler; import javax.activation.DataHandler;
import javax.activation.FileDataSource; import javax.activation.FileDataSource;

import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.Session; import javax.mail.Session;
@@ -72,17 +79,75 @@ import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeMultipart;

import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;


/** /**
* Uses the JavaMail classes to send Mime format email. * Uses the JavaMail classes to send Mime format email.
* *
* @author roxspring@yahoo.com Rob Oxspring * @author roxspring@yahoo.com Rob Oxspring
* @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a>
* @since Ant 1.5 * @since Ant 1.5
*/ */
class MimeMailer extends Mailer { class MimeMailer extends Mailer {
/** Sends the email */
public void send() {
// Default character set
private static final String defaultCharset = System.getProperty("file.encoding");

// To work poperly with national charsets we have to use
// implementation of interface javax.activation.DataSource
/**
* @since Ant 1.6
*/
class StringDataSource implements javax.activation.DataSource {
private String data=null;
private String type=null;
private String charset = null;
private ByteArrayOutputStream out;

public InputStream getInputStream() throws IOException {
if(data == null && out == null)
throw new IOException("No data");
else {
if(out!=null) {
data=(data!=null)?data.concat(out.toString(charset)):out.toString(charset);
out=null;
}
return new ByteArrayInputStream(data.getBytes(charset));
}
}

public OutputStream getOutputStream() throws IOException {
if(out==null) {
out=new ByteArrayOutputStream();
}
return out;
}

public void setContentType(String type) {
this.type=type.toLowerCase();
}

public String getContentType() {
if(type !=null && type.indexOf("charset")>0 && type.startsWith("text/"))
return type;
// Must be like "text/plain; charset=windows-1251"
return type!=null?type.concat("; charset=".concat(charset)):
"text/plain".concat("; charset=".concat(charset));
}

public String getName() {
return "StringDataSource";
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getCharset() {
return charset;
}
}

/** Sends the email */
public void send() {
try { try {
Properties props = new Properties(); Properties props = new Properties();


@@ -113,20 +178,38 @@ class MimeMailer extends Mailer {
msg.setRecipients(Message.RecipientType.BCC, msg.setRecipients(Message.RecipientType.BCC,
internetAddresses(bccList)); internetAddresses(bccList));


if (subject != null) {
msg.setSubject(subject);
// Choosing character set of the mail message
// First: looking it from MimeType
String charset = parseCharSetFromMimeType(message.getMimeType());
if(charset!=null) {
// Assign/reassign message charset from MimeType
message.setCharset(charset);
}
// Next: looking if charset having explict definition
else {
charset = message.getCharset();
if(charset==null) {
// Using default
charset=defaultCharset;
message.setCharset(charset);
}
} }
msg.addHeader("Date", getDate());


ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baos);
// Using javax.activation.DataSource paradigm
StringDataSource sds = new StringDataSource();
sds.setContentType(message.getMimeType());
sds.setCharset(charset);


if (subject != null)
msg.setSubject(subject,charset);
msg.addHeader("Date", getDate());

PrintStream out = new PrintStream(sds.getOutputStream());
message.print(out); message.print(out);
out.close(); out.close();


MimeBodyPart textbody = new MimeBodyPart(); MimeBodyPart textbody = new MimeBodyPart();

textbody.setContent(baos.toString(), message.getMimeType());
textbody.setDataHandler(new DataHandler(sds));
attachments.addBodyPart(textbody); attachments.addBodyPart(textbody);


Enumeration e = files.elements(); Enumeration e = files.elements();
@@ -177,5 +260,15 @@ class MimeMailer extends Mailer {


return addrs; return addrs;
} }

private String parseCharSetFromMimeType(String type){
int pos;
if(type==null || (pos=type.indexOf("charset"))<0)
return null;
// Assuming mime type in form "text/XXXX; charset=XXXXXX"
StringTokenizer token = new StringTokenizer(type.substring(pos),"=; ");
token.nextToken();// Skip 'charset='
return token.nextToken();
}
} }



Loading…
Cancel
Save