All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tools.ant.taskdefs.email.MimeMailer Maven / Gradle / Ivy

There is a newer version: 1.0-rc5
Show newest version
/*
 * Copyright  2002-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
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 java.security.Security;
import java.security.Provider;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Message;
import javax.mail.Transport;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
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.
 *
 * @since Ant 1.5
 */
public class MimeMailer extends Mailer {
    /** Default character set */
    private static final String DEFAULT_CHARSET
        = System.getProperty("file.encoding");

    // To work properly 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();

            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", String.valueOf(port));

            // Aside, the JDK is clearly unaware of the Scottish
            // 'session', which involves excessive quantities of
            // alcohol :-)
            Session sesh;
            Authenticator auth;
            if (SSL) {
                try {
                    Provider p
                        = (Provider) Class.forName("com.sun.net.ssl.internal.ssl.Provider").newInstance();
                    Security.addProvider(p);
                } catch (Exception e) {
                    throw new BuildException("could not instantiate ssl "
                        + "security provider, check that you have JSSE in "
                        + "your classpath");
                }
                final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
                // SMTP provider
                props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
                props.put("mail.smtp.socketFactory.fallback", "false");
            }
            if (user == null && password == null) {
                sesh = Session.getDefaultInstance(props, null);
            } else {
                props.put("mail.smtp.auth", "true");
                auth = new SimpleAuthenticator(user, password);
                sesh = Session.getInstance(props, auth);
            }
            //create the message
            MimeMessage msg = new MimeMessage(sesh);
            MimeMultipart attachments = new MimeMultipart();

            //set the sender
            if (from.getName() == null) {
                msg.setFrom(new InternetAddress(from.getAddress()));
            } else {
                msg.setFrom(new InternetAddress(from.getAddress(),
                    from.getName()));
            }
            // set the reply to addresses
            msg.setReplyTo(internetAddresses(replyToList));
            msg.setRecipients(Message.RecipientType.TO,
                internetAddresses(toList));
            msg.setRecipients(Message.RecipientType.CC,
                internetAddresses(ccList));
            msg.setRecipients(Message.RecipientType.BCC,
                internetAddresses(bccList));

            // 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);
            } else {
                // Next: looking if charset having explicit definition
                charset = message.getCharset();
                if (charset == null) {
                    // Using default
                    charset = DEFAULT_CHARSET;
                    message.setCharset(charset);
                }
            }

            // 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.setDataHandler(new DataHandler(sds));
            attachments.addBodyPart(textbody);

            Enumeration e = files.elements();

            while (e.hasMoreElements()) {
                File file = (File) e.nextElement();

                MimeBodyPart body;

                body = new MimeBodyPart();
                if (!file.exists() || !file.canRead()) {
                    throw new BuildException("File \"" + file.getAbsolutePath()
                         + "\" does not exist or is not "
                         + "readable.");
                }
                FileDataSource fileData = new FileDataSource(file);
                DataHandler fileDataHandler = new DataHandler(fileData);

                body.setDataHandler(fileDataHandler);
                body.setFileName(file.getName());
                attachments.addBodyPart(body);
            }

            msg.setContent(attachments);
            Transport.send(msg);
        } catch (MessagingException e) {
            throw new BuildException("Problem while sending mime mail:", e);
        } catch (IOException e) {
            throw new BuildException("Problem while sending mime mail:", e);
        }
    }


    private static InternetAddress[] internetAddresses(Vector list)
         throws AddressException, UnsupportedEncodingException {
        InternetAddress[] addrs = new InternetAddress[list.size()];

        for (int i = 0; i < list.size(); ++i) {
            EmailAddress addr = (EmailAddress) list.elementAt(i);

            if (addr.getName() == null) {
                addrs[i] = new InternetAddress(addr.getAddress());
            } else {
                addrs[i] = new InternetAddress(addr.getAddress(),
                    addr.getName());
            }
        }

        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();
    }

    static class SimpleAuthenticator extends Authenticator {
        private String user = null;
        private String password = null;
        public SimpleAuthenticator(String user, String password) {
            this.user = user;
            this.password = password;
        }
        public PasswordAuthentication getPasswordAuthentication() {

            return new PasswordAuthentication(user, password);
        }
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy