antoine 2003/04/17 10:09:35
Modified: src/main/org/apache/tools/ant/taskdefs/email MimeMailer.java Message.java EmailTask.java docs/manual/CoreTasks mail.html Log: add international support for mailtask - bug report 15434 Revision Changes Path 1.9 +103 -10 ant/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java Index: MimeMailer.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- MimeMailer.java 10 Feb 2003 14:13:45 -0000 1.8 +++ MimeMailer.java 17 Apr 2003 17:09:35 -0000 1.9 @@ -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.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 [EMAIL PROTECTED] Rob Oxspring + * @author <a href="mailto:[EMAIL PROTECTED]">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 @@ 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); } - msg.addHeader("Date", getDate()); + // Next: looking if charset having explict definition + else { + charset = message.getCharset(); + if(charset==null) { + // Using default + charset=defaultCharset; + message.setCharset(charset); + } + } + + // Using javax.activation.DataSource paradigm + StringDataSource sds = new StringDataSource(); + sds.setContentType(message.getMimeType()); + sds.setCharset(charset); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(baos); + 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(); @@ -176,6 +259,16 @@ } 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(); } } 1.8 +29 -3 ant/src/main/org/apache/tools/ant/taskdefs/email/Message.java Index: Message.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/email/Message.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- Message.java 4 Apr 2003 13:51:11 -0000 1.7 +++ Message.java 17 Apr 2003 17:09:35 -0000 1.8 @@ -57,13 +57,17 @@ 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 [EMAIL PROTECTED] Rob Oxspring + * @author <a href="mailto:[EMAIL PROTECTED]">Aleksandr Ishutin</a> * @since Ant 1.5 */ public class Message extends ProjectComponent { @@ -71,7 +75,7 @@ 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 @@ * @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 @@ try { BufferedReader in = new BufferedReader(freader); String line = null; - while ((line = in.readLine()) != null) { out.println(getProject().replaceProperties(line)); } @@ -164,6 +172,7 @@ } else { out.println(getProject().replaceProperties(buffer.substring(0))); } + out.flush(); } @@ -174,6 +183,23 @@ */ 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.17 +38 -2 ant/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java Index: EmailTask.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- EmailTask.java 10 Feb 2003 14:13:45 -0000 1.16 +++ EmailTask.java 17 Apr 2003 17:09:35 -0000 1.17 @@ -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 @@ * @author [EMAIL PROTECTED] Erik Hatcher * @author [EMAIL PROTECTED] Paulo Gaspar * @author [EMAIL PROTECTED] Rob Oxspring + * @author <a href="mailto:[EMAIL PROTECTED]">Aleksandr Ishutin</a> * @since Ant 1.5 * @ant.task name="mail" category="network" */ @@ -132,6 +133,8 @@ /** file list */ private Vector files = new Vector(); private Vector filesets = new Vector(); + /** Character set for MimeMailer*/ + private String charset=null; /** @@ -410,7 +413,7 @@ 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 @@ 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 @@ 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; } } 1.17 +29 -0 ant/docs/manual/CoreTasks/mail.html Index: mail.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/mail.html,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- mail.html 28 Mar 2003 15:03:55 -0000 1.16 +++ mail.html 17 Apr 2003 17:09:35 -0000 1.17 @@ -101,6 +101,13 @@ <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> <td align="center" valign="top">No</td> @@ -151,6 +158,13 @@ <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 @@ 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="[EMAIL PROTECTED]" mailport="25" subject="Test build" charset="utf-8"> + <from address="[EMAIL PROTECTED]"/> + <to address="[EMAIL PROTECTED]" /> + <message>some international text:${line2}</message> +</mail> +</pre></blockquote> + +<p>Sends an eMail from <i>[EMAIL PROTECTED]</i> to <i>[EMAIL PROTECTED]</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>