git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274480 13f79535-47bb-0310-9956-ffa450edef68master
@@ -100,6 +100,13 @@ Library Dependencies</a> for more information. | |||
<code>auto</code>. The default value is <code>auto</code>.</td> | |||
<td align="center" valign="top">No</td> | |||
</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> | |||
<td valign="top">subject</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 align="center" valign="top">No</td> | |||
</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> | |||
<p>If the <code>src</code> attribute is not specified, then text can be added | |||
@@ -187,6 +201,21 @@ the <code><message></code> element.</p> | |||
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> | |||
will be replaced with the <code>buildname</code> property's value.</p> | |||
<blockquote><pre> | |||
<property name="line2" value="some_international_message"/> | |||
<echo message="${line2}"/> | |||
<mail mailhost="somehost@xyz.com" mailport="25" subject="Test build" charset="utf-8"> | |||
<from address="me@myist.com"/> | |||
<to address="all@xyz.com" /> | |||
<message>some international text:${line2}</message> | |||
</mail> | |||
</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> | |||
<p align="center">Copyright © 2000-2003 Apache Software Foundation. All rights | |||
Reserved.</p> | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* 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. | |||
* | |||
* 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 paulo.gaspar@krankikom.de Paulo Gaspar | |||
* @author roxspring@imapmail.org Rob Oxspring | |||
* @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a> | |||
* @since Ant 1.5 | |||
* @ant.task name="mail" category="network" | |||
*/ | |||
@@ -132,6 +133,8 @@ public class EmailTask | |||
/** file list */ | |||
private Vector files = new Vector(); | |||
private Vector filesets = new Vector(); | |||
/** Character set for MimeMailer*/ | |||
private String charset=null; | |||
/** | |||
@@ -410,7 +413,7 @@ public class EmailTask | |||
autoFound = true; | |||
log("Using MIME mail", Project.MSG_VERBOSE); | |||
} 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); | |||
} | |||
} | |||
// 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 | |||
Enumeration e = filesets.elements(); | |||
@@ -519,10 +531,34 @@ public class EmailTask | |||
if (failOnError) { | |||
throw e; | |||
} | |||
} | |||
catch(Exception e){ | |||
log("Failed to send email", Project.MSG_WARN); | |||
if (failOnError) { | |||
throw new BuildException(e); | |||
} | |||
} finally { | |||
message = savedMessage; | |||
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; | |||
} | |||
} | |||
@@ -57,13 +57,17 @@ import java.io.BufferedReader; | |||
import java.io.File; | |||
import java.io.FileReader; | |||
import java.io.IOException; | |||
import java.io.OutputStreamWriter; | |||
import java.io.PrintStream; | |||
import java.io.PrintWriter; | |||
import org.apache.tools.ant.ProjectComponent; | |||
/** | |||
* Class representing an email message. | |||
* | |||
* @author roxspring@yahoo.com Rob Oxspring | |||
* @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a> | |||
* @since Ant 1.5 | |||
*/ | |||
public class Message extends ProjectComponent { | |||
@@ -71,7 +75,7 @@ public class Message extends ProjectComponent { | |||
private StringBuffer buffer = new StringBuffer(); | |||
private String mimeType = "text/plain"; | |||
private boolean specified = false; | |||
private String charset=null; | |||
/** Creates a new empty message */ | |||
public Message() { | |||
@@ -145,8 +149,13 @@ public class Message extends ProjectComponent { | |||
* @param out The print stream to write to | |||
* @throws IOException if an error occurs | |||
*/ | |||
public void print(PrintStream out) | |||
public void print(PrintStream ps) | |||
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) { | |||
// Read message from a file | |||
FileReader freader = new FileReader(messageSource); | |||
@@ -154,7 +163,6 @@ public class Message extends ProjectComponent { | |||
try { | |||
BufferedReader in = new BufferedReader(freader); | |||
String line = null; | |||
while ((line = in.readLine()) != null) { | |||
out.println(getProject().replaceProperties(line)); | |||
} | |||
@@ -164,6 +172,7 @@ public class Message extends ProjectComponent { | |||
} else { | |||
out.println(getProject().replaceProperties(buffer.substring(0))); | |||
} | |||
out.flush(); | |||
} | |||
@@ -175,5 +184,22 @@ public class Message extends ProjectComponent { | |||
public boolean isMimeTypeSpecified() { | |||
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; | |||
} | |||
} | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* 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. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
@@ -53,16 +53,23 @@ | |||
*/ | |||
package org.apache.tools.ant.taskdefs.email; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.io.PrintStream; | |||
import java.io.UnsupportedEncodingException; | |||
import java.util.Enumeration; | |||
import java.util.Properties; | |||
import java.util.StringTokenizer; | |||
import java.util.Vector; | |||
import javax.activation.DataHandler; | |||
import javax.activation.FileDataSource; | |||
import javax.mail.Message; | |||
import javax.mail.MessagingException; | |||
import javax.mail.Session; | |||
@@ -72,17 +79,75 @@ import javax.mail.internet.InternetAddress; | |||
import javax.mail.internet.MimeBodyPart; | |||
import javax.mail.internet.MimeMessage; | |||
import javax.mail.internet.MimeMultipart; | |||
import org.apache.tools.ant.BuildException; | |||
/** | |||
* Uses the JavaMail classes to send Mime format email. | |||
* | |||
* @author roxspring@yahoo.com Rob Oxspring | |||
* @author <a href="mailto:ishu@akm.ru">Aleksandr Ishutin</a> | |||
* @since Ant 1.5 | |||
*/ | |||
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 { | |||
Properties props = new Properties(); | |||
@@ -113,20 +178,38 @@ class MimeMailer extends Mailer { | |||
msg.setRecipients(Message.RecipientType.BCC, | |||
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); | |||
out.close(); | |||
MimeBodyPart textbody = new MimeBodyPart(); | |||
textbody.setContent(baos.toString(), message.getMimeType()); | |||
textbody.setDataHandler(new DataHandler(sds)); | |||
attachments.addBodyPart(textbody); | |||
Enumeration e = files.elements(); | |||
@@ -177,5 +260,15 @@ class MimeMailer extends Mailer { | |||
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(); | |||
} | |||
} | |||