KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > email > MimeMailer


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.email;
19
20 import java.io.File JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.PrintStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.io.ByteArrayInputStream JavaDoc;
26 import java.io.ByteArrayOutputStream JavaDoc;
27 import java.io.UnsupportedEncodingException JavaDoc;
28
29 import java.util.Vector JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Properties JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.StringTokenizer JavaDoc;
34
35 import java.security.Provider JavaDoc;
36 import java.security.Security JavaDoc;
37
38 import javax.activation.DataHandler JavaDoc;
39 import javax.activation.FileDataSource JavaDoc;
40
41 import javax.mail.Message JavaDoc;
42 import javax.mail.Session JavaDoc;
43 import javax.mail.Transport JavaDoc;
44 import javax.mail.Authenticator JavaDoc;
45 import javax.mail.MessagingException JavaDoc;
46 import javax.mail.PasswordAuthentication JavaDoc;
47 import javax.mail.internet.MimeMessage JavaDoc;
48 import javax.mail.internet.MimeBodyPart JavaDoc;
49 import javax.mail.internet.MimeMultipart JavaDoc;
50 import javax.mail.internet.InternetAddress JavaDoc;
51 import javax.mail.internet.AddressException JavaDoc;
52
53 import org.apache.tools.ant.BuildException;
54
55 /**
56  * Uses the JavaMail classes to send Mime format email.
57  *
58  * @since Ant 1.5
59  */

60 public class MimeMailer extends Mailer {
61     private static final String JavaDoc SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
62
63     /** Default character set */
64     private static final String JavaDoc DEFAULT_CHARSET
65         = System.getProperty("file.encoding");
66
67     // To work properly with national charsets we have to use
68
// implementation of interface javax.activation.DataSource
69
/**
70      * String data source implementation.
71      * @since Ant 1.6
72      */

73     class StringDataSource implements javax.activation.DataSource JavaDoc {
74         private String JavaDoc data = null;
75         private String JavaDoc type = null;
76         private String JavaDoc charset = null;
77         private ByteArrayOutputStream JavaDoc out;
78
79         public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
80             if (data == null && out == null) {
81                 throw new IOException JavaDoc("No data");
82             }
83             if (out != null) {
84                 String JavaDoc encodedOut = out.toString(charset);
85                 data = (data != null) ? data.concat(encodedOut) : encodedOut;
86                 out = null;
87             }
88             return new ByteArrayInputStream JavaDoc(data.getBytes(charset));
89         }
90
91         public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
92             out = (out == null) ? new ByteArrayOutputStream JavaDoc() : out;
93             return out;
94         }
95
96         public void setContentType(String JavaDoc type) {
97             this.type = type.toLowerCase();
98         }
99
100         public String JavaDoc getContentType() {
101             if (type != null && type.indexOf("charset") > 0
102                 && type.startsWith("text/")) {
103                 return type;
104             }
105             // Must be like "text/plain; charset=windows-1251"
106
return new StringBuffer JavaDoc(type != null ? type : "text/plain").append(
107                 "; charset=").append(charset).toString();
108         }
109
110         public String JavaDoc getName() {
111             return "StringDataSource";
112         }
113
114         public void setCharset(String JavaDoc charset) {
115             this.charset = charset;
116         }
117
118         public String JavaDoc getCharset() {
119             return charset;
120         }
121     }
122
123     /**
124      * Send the email.
125      *
126      * @throws BuildException if the email can't be sent.
127      */

128     public void send() {
129         try {
130             Properties JavaDoc props = new Properties JavaDoc();
131
132             props.put("mail.smtp.host", host);
133             props.put("mail.smtp.port", String.valueOf(port));
134
135             // Aside, the JDK is clearly unaware of the Scottish
136
// 'session', which involves excessive quantities of
137
// alcohol :-)
138
Session JavaDoc sesh;
139             Authenticator JavaDoc auth;
140             if (SSL) {
141                 try {
142                     Provider JavaDoc p = (Provider JavaDoc) Class.forName(
143                         "com.sun.net.ssl.internal.ssl.Provider").newInstance();
144                     Security.addProvider(p);
145                 } catch (Exception JavaDoc e) {
146                     throw new BuildException("could not instantiate ssl "
147                         + "security provider, check that you have JSSE in "
148                         + "your classpath");
149                 }
150                 // SMTP provider
151
props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
152                 props.put("mail.smtp.socketFactory.fallback", "false");
153             }
154             if (user == null && password == null) {
155                 sesh = Session.getDefaultInstance(props, null);
156             } else {
157                 props.put("mail.smtp.auth", "true");
158                 auth = new SimpleAuthenticator(user, password);
159                 sesh = Session.getInstance(props, auth);
160             }
161             //create the message
162
MimeMessage JavaDoc msg = new MimeMessage JavaDoc(sesh);
163             MimeMultipart JavaDoc attachments = new MimeMultipart JavaDoc();
164
165             //set the sender
166
if (from.getName() == null) {
167                 msg.setFrom(new InternetAddress JavaDoc(from.getAddress()));
168             } else {
169                 msg.setFrom(new InternetAddress JavaDoc(from.getAddress(),
170                     from.getName()));
171             }
172             // set the reply to addresses
173
msg.setReplyTo(internetAddresses(replyToList));
174             msg.setRecipients(Message.RecipientType.TO,
175                 internetAddresses(toList));
176             msg.setRecipients(Message.RecipientType.CC,
177                 internetAddresses(ccList));
178             msg.setRecipients(Message.RecipientType.BCC,
179                 internetAddresses(bccList));
180
181             // Choosing character set of the mail message
182
// First: looking it from MimeType
183
String JavaDoc charset = parseCharSetFromMimeType(message.getMimeType());
184             if (charset != null) {
185                 // Assign/reassign message charset from MimeType
186
message.setCharset(charset);
187             } else {
188                 // Next: looking if charset having explicit definition
189
charset = message.getCharset();
190                 if (charset == null) {
191                     // Using default
192
charset = DEFAULT_CHARSET;
193                     message.setCharset(charset);
194                 }
195             }
196             // Using javax.activation.DataSource paradigm
197
StringDataSource sds = new StringDataSource();
198             sds.setContentType(message.getMimeType());
199             sds.setCharset(charset);
200
201             if (subject != null) {
202                 msg.setSubject(subject, charset);
203             }
204             msg.addHeader("Date", getDate());
205
206             for (Iterator JavaDoc iter = headers.iterator(); iter.hasNext();) {
207                 Header h = (Header) iter.next();
208                 msg.addHeader(h.getName(), h.getValue());
209             }
210             PrintStream JavaDoc out = new PrintStream JavaDoc(sds.getOutputStream());
211             message.print(out);
212             out.close();
213
214             MimeBodyPart JavaDoc textbody = new MimeBodyPart JavaDoc();
215             textbody.setDataHandler(new DataHandler JavaDoc(sds));
216             attachments.addBodyPart(textbody);
217
218             Enumeration JavaDoc e = files.elements();
219
220             while (e.hasMoreElements()) {
221                 File JavaDoc file = (File JavaDoc) e.nextElement();
222
223                 MimeBodyPart JavaDoc body;
224
225                 body = new MimeBodyPart JavaDoc();
226                 if (!file.exists() || !file.canRead()) {
227                     throw new BuildException("File \"" + file.getAbsolutePath()
228                          + "\" does not exist or is not "
229                          + "readable.");
230                 }
231                 FileDataSource JavaDoc fileData = new FileDataSource JavaDoc(file);
232                 DataHandler JavaDoc fileDataHandler = new DataHandler JavaDoc(fileData);
233
234                 body.setDataHandler(fileDataHandler);
235                 body.setFileName(file.getName());
236                 attachments.addBodyPart(body);
237             }
238             msg.setContent(attachments);
239             Transport.send(msg);
240         } catch (MessagingException JavaDoc e) {
241             throw new BuildException("Problem while sending mime mail:", e);
242         } catch (IOException JavaDoc e) {
243             throw new BuildException("Problem while sending mime mail:", e);
244         }
245     }
246
247     private static InternetAddress JavaDoc[] internetAddresses(Vector JavaDoc list)
248         throws AddressException JavaDoc, UnsupportedEncodingException JavaDoc {
249         InternetAddress JavaDoc[] addrs = new InternetAddress JavaDoc[list.size()];
250
251         for (int i = 0; i < list.size(); ++i) {
252             EmailAddress addr = (EmailAddress) list.elementAt(i);
253
254             String JavaDoc name = addr.getName();
255             addrs[i] = (name == null)
256                 ? new InternetAddress JavaDoc(addr.getAddress())
257                 : new InternetAddress JavaDoc(addr.getAddress(), name);
258         }
259         return addrs;
260     }
261
262     private String JavaDoc parseCharSetFromMimeType(String JavaDoc type) {
263         int pos;
264         if (type == null || (pos = type.indexOf("charset")) < 0) {
265           return null;
266         }
267         // Assuming mime type in form "text/XXXX; charset=XXXXXX"
268
StringTokenizer JavaDoc token = new StringTokenizer JavaDoc(type.substring(pos), "=; ");
269         token.nextToken(); // Skip 'charset='
270
return token.nextToken();
271     }
272
273     static class SimpleAuthenticator extends Authenticator JavaDoc {
274         private String JavaDoc user = null;
275         private String JavaDoc password = null;
276         public SimpleAuthenticator(String JavaDoc user, String JavaDoc password) {
277             this.user = user;
278             this.password = password;
279         }
280         public PasswordAuthentication JavaDoc getPasswordAuthentication() {
281
282             return new PasswordAuthentication JavaDoc(user, password);
283         }
284     }
285 }
286
287
Popular Tags