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>
  +&lt;property name=&quot;line2&quot; 
value=&quot;some_international_message&quot;/&gt;
  +&lt;echo message=&quot;${line2}&quot;/&gt;
  +
  +&lt;mail mailhost=&quot;[EMAIL PROTECTED]&quot; mailport=&quot;25&quot; 
subject=&quot;Test build&quot;  charset=&quot;utf-8&quot;&gt;
  +  &lt;from address=&quot;[EMAIL PROTECTED]&quot;/&gt;
  +  &lt;to address=&quot;[EMAIL PROTECTED]&quot; /&gt;
  +  &lt;message&gt;some international text:${line2}&lt;/message&gt;
  +&lt;/mail&gt;
  +</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 &copy; 2000-2003 Apache Software Foundation. All 
rights
   Reserved.</p>
  
  
  

Reply via email to