DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15434>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15434 MimeMailer doesn't work properly with national charset Summary: MimeMailer doesn't work properly with national charset Product: Ant Version: 1.6Alpha (nightly) Platform: All OS/Version: All Status: NEW Severity: Normal Priority: Other Component: Optional Tasks AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] MimeMailer doesn't work properly with national charset while build file locale differ from default OS locale/charset I'm using WinXP on my desktop with default ru_RU locle - charset windows-1251 We've got nuber of servers under Linux and Solaris with different locales: ru_RU.KOI8-R, ru_RU.ISO8859-5 and en_EN.ISO8859-1 When I deploy some my projects/services using ant I send e-mail about deployment completition. All national symbols looks like ??????????? in mail Subject and Body. Same problems appears in Ant 1.5.1 My suggestions to fix this problem: Index: EmailTask.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java,v retrieving revision 1.15 diff -u -r1.15 EmailTask.java --- EmailTask.java 4 Dec 2002 16:42:32 -0000 1.15 +++ EmailTask.java 16 Dec 2002 15:48:27 -0000 @@ -132,6 +132,8 @@ /** file list */ private Vector files = new Vector(); private Vector filesets = new Vector(); + /** Character set for MimeMailer*/ + private String charset=null; /** @@ -410,7 +412,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 +470,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 +530,32 @@ 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> + */ + public void setCharset(String charset) { + this.charset = charset; + } + /** + * Returns the character set of mail message. + * + * @return Charset of mail message. + */ + public String getCharset() { + return charset; } } # Index: Message.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/email/Message.java,v retrieving revision 1.5 diff -u -r1.5 Message.java --- Message.java 25 Jul 2002 15:21:10 -0000 1.5 +++ Message.java 16 Dec 2002 15:46:44 -0000 @@ -57,7 +57,10 @@ 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; /** @@ -71,7 +74,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 +148,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 +162,6 @@ try { BufferedReader in = new BufferedReader(freader); String line = null; - while ((line = in.readLine()) != null) { out.println(getProject().replaceProperties(line)); } @@ -164,6 +171,7 @@ } else { out.println(getProject().replaceProperties(buffer.toString())); } + out.flush(); } @@ -174,6 +182,21 @@ */ public boolean isMimeTypeSpecified() { return specified; + } + /** + * Sets the character set of mail message. + * Will be ignored if mimeType contains ....; Charset=... substring. + */ + public void setCharset(String charset) { + this.charset = charset; + } + /** + * Returns the charset of mail message. + * + * @return Charset of mail message. + */ + public String getCharset() { + return charset; } } # Index: MimeMailer.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java,v retrieving revision 1.7 diff -u -r1.7 MimeMailer.java --- MimeMailer.java 22 Jun 2002 23:38:35 -0000 1.7 +++ MimeMailer.java 16 Dec 2002 15:46:02 -0000 @@ -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,6 +79,7 @@ import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; + import org.apache.tools.ant.BuildException; /** @@ -81,8 +89,61 @@ * @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 + 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 +174,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 +255,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(); } } -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>