From 416d46165ba953cbc74387d62e82515e8180208a Mon Sep 17 00:00:00 2001 From: Antoine Levy-Lambert Date: Thu, 17 Apr 2003 17:09:35 +0000 Subject: [PATCH] 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 --- docs/manual/CoreTasks/mail.html | 29 +++++ .../tools/ant/taskdefs/email/EmailTask.java | 40 ++++++- .../tools/ant/taskdefs/email/Message.java | 32 ++++- .../tools/ant/taskdefs/email/MimeMailer.java | 113 ++++++++++++++++-- 4 files changed, 199 insertions(+), 15 deletions(-) diff --git a/docs/manual/CoreTasks/mail.html b/docs/manual/CoreTasks/mail.html index 5d2254435..234472873 100644 --- a/docs/manual/CoreTasks/mail.html +++ b/docs/manual/CoreTasks/mail.html @@ -100,6 +100,13 @@ Library Dependencies for more information. auto. The default value is auto. No + + charset + Character set of the email.
+ You can also set the charset in the message nested element.
+ These options are mutually exclusive. + No + subject Email subject line. @@ -151,6 +158,13 @@ attributes:

The content type to use for the message. No + + charset + Character set of the message
+ You can also set the charset as attribute of the enclosing mail task.
+ These options are mutually exclusive. + No +

If the src attribute is not specified, then text can be added @@ -187,6 +201,21 @@ the <message> element.

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. ${buildname} will be replaced with the buildname property's value.

+ +
+<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>
+
+ +

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


Copyright © 2000-2003 Apache Software Foundation. All rights Reserved.

diff --git a/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java b/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java index 781f52ced..5c97d5afc 100644 --- a/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java @@ -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 Aleksandr Ishutin * @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 mime + * @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; + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/email/Message.java b/src/main/org/apache/tools/ant/taskdefs/email/Message.java index 7be15e1ba..2f3bb1b3f 100644 --- a/src/main/org/apache/tools/ant/taskdefs/email/Message.java +++ b/src/main/org/apache/tools/ant/taskdefs/email/Message.java @@ -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 Aleksandr Ishutin * @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; + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java b/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java index 706009161..246d38b6c 100644 --- a/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java +++ b/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java @@ -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 Aleksandr Ishutin * @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(); + } }