source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 9.8 KB
Line 
1/*
2 * Copyright 2002-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.email;
18
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.File;
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.OutputStream;
25import java.io.PrintStream;
26import java.io.UnsupportedEncodingException;
27
28import java.util.Enumeration;
29import java.util.Properties;
30import java.util.StringTokenizer;
31import java.util.Vector;
32import java.security.Security;
33import java.security.Provider;
34
35import javax.activation.DataHandler;
36import javax.activation.FileDataSource;
37
38import javax.mail.Authenticator;
39import javax.mail.PasswordAuthentication;
40import javax.mail.Session;
41import javax.mail.Message;
42import javax.mail.Transport;
43import javax.mail.MessagingException;
44import javax.mail.internet.AddressException;
45import javax.mail.internet.InternetAddress;
46import javax.mail.internet.MimeBodyPart;
47import javax.mail.internet.MimeMessage;
48import javax.mail.internet.MimeMultipart;
49
50import org.apache.tools.ant.BuildException;
51
52/**
53 * Uses the JavaMail classes to send Mime format email.
54 *
55 * @since Ant 1.5
56 */
57public class MimeMailer extends Mailer {
58 /** Default character set */
59 private static final String DEFAULT_CHARSET
60 = System.getProperty("file.encoding");
61
62 // To work properly with national charsets we have to use
63 // implementation of interface javax.activation.DataSource
64 /**
65 * @since Ant 1.6
66 */
67 class StringDataSource implements javax.activation.DataSource {
68 private String data = null;
69 private String type = null;
70 private String charset = null;
71 private ByteArrayOutputStream out;
72
73 public InputStream getInputStream() throws IOException {
74 if (data == null && out == null) {
75 throw new IOException("No data");
76 } else {
77 if (out != null) {
78 data = (data != null) ? data.concat(out.toString(charset)) : out.toString(charset);
79 out = null;
80 }
81 return new ByteArrayInputStream(data.getBytes(charset));
82 }
83 }
84
85 public OutputStream getOutputStream() throws IOException {
86 if (out == null) {
87 out = new ByteArrayOutputStream();
88 }
89 return out;
90 }
91
92 public void setContentType(String type) {
93 this.type = type.toLowerCase();
94 }
95
96 public String getContentType() {
97 if (type != null && type.indexOf("charset") > 0 && type.startsWith("text/")) {
98 return type;
99 }
100 // Must be like "text/plain; charset=windows-1251"
101 return type != null ? type.concat("; charset=".concat(charset))
102 : "text/plain".concat("; charset=".concat(charset));
103 }
104
105 public String getName() {
106 return "StringDataSource";
107 }
108 public void setCharset(String charset) {
109 this.charset = charset;
110 }
111 public String getCharset() {
112 return charset;
113 }
114 }
115
116 /** Sends the email */
117 public void send() {
118 try {
119 Properties props = new Properties();
120
121 props.put("mail.smtp.host", host);
122 props.put("mail.smtp.port", String.valueOf(port));
123
124 // Aside, the JDK is clearly unaware of the Scottish
125 // 'session', which involves excessive quantities of
126 // alcohol :-)
127 Session sesh;
128 Authenticator auth;
129 if (SSL) {
130 try {
131 Provider p
132 = (Provider) Class.forName("com.sun.net.ssl.internal.ssl.Provider").newInstance();
133 Security.addProvider(p);
134 } catch (Exception e) {
135 throw new BuildException("could not instantiate ssl "
136 + "security provider, check that you have JSSE in "
137 + "your classpath");
138 }
139 final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
140 // SMTP provider
141 props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
142 props.put("mail.smtp.socketFactory.fallback", "false");
143 }
144 if (user == null && password == null) {
145 sesh = Session.getDefaultInstance(props, null);
146 } else {
147 props.put("mail.smtp.auth", "true");
148 auth = new SimpleAuthenticator(user, password);
149 sesh = Session.getInstance(props, auth);
150 }
151 //create the message
152 MimeMessage msg = new MimeMessage(sesh);
153 MimeMultipart attachments = new MimeMultipart();
154
155 //set the sender
156 if (from.getName() == null) {
157 msg.setFrom(new InternetAddress(from.getAddress()));
158 } else {
159 msg.setFrom(new InternetAddress(from.getAddress(),
160 from.getName()));
161 }
162 // set the reply to addresses
163 msg.setReplyTo(internetAddresses(replyToList));
164 msg.setRecipients(Message.RecipientType.TO,
165 internetAddresses(toList));
166 msg.setRecipients(Message.RecipientType.CC,
167 internetAddresses(ccList));
168 msg.setRecipients(Message.RecipientType.BCC,
169 internetAddresses(bccList));
170
171 // Choosing character set of the mail message
172 // First: looking it from MimeType
173 String charset = parseCharSetFromMimeType(message.getMimeType());
174 if (charset != null) {
175 // Assign/reassign message charset from MimeType
176 message.setCharset(charset);
177 } else {
178 // Next: looking if charset having explicit definition
179 charset = message.getCharset();
180 if (charset == null) {
181 // Using default
182 charset = DEFAULT_CHARSET;
183 message.setCharset(charset);
184 }
185 }
186
187 // Using javax.activation.DataSource paradigm
188 StringDataSource sds = new StringDataSource();
189 sds.setContentType(message.getMimeType());
190 sds.setCharset(charset);
191
192 if (subject != null) {
193 msg.setSubject(subject, charset);
194 }
195 msg.addHeader("Date", getDate());
196
197 PrintStream out = new PrintStream(sds.getOutputStream());
198 message.print(out);
199 out.close();
200
201 MimeBodyPart textbody = new MimeBodyPart();
202 textbody.setDataHandler(new DataHandler(sds));
203 attachments.addBodyPart(textbody);
204
205 Enumeration e = files.elements();
206
207 while (e.hasMoreElements()) {
208 File file = (File) e.nextElement();
209
210 MimeBodyPart body;
211
212 body = new MimeBodyPart();
213 if (!file.exists() || !file.canRead()) {
214 throw new BuildException("File \"" + file.getAbsolutePath()
215 + "\" does not exist or is not "
216 + "readable.");
217 }
218 FileDataSource fileData = new FileDataSource(file);
219 DataHandler fileDataHandler = new DataHandler(fileData);
220
221 body.setDataHandler(fileDataHandler);
222 body.setFileName(file.getName());
223 attachments.addBodyPart(body);
224 }
225
226 msg.setContent(attachments);
227 Transport.send(msg);
228 } catch (MessagingException e) {
229 throw new BuildException("Problem while sending mime mail:", e);
230 } catch (IOException e) {
231 throw new BuildException("Problem while sending mime mail:", e);
232 }
233 }
234
235
236 private static InternetAddress[] internetAddresses(Vector list)
237 throws AddressException, UnsupportedEncodingException {
238 InternetAddress[] addrs = new InternetAddress[list.size()];
239
240 for (int i = 0; i < list.size(); ++i) {
241 EmailAddress addr = (EmailAddress) list.elementAt(i);
242
243 if (addr.getName() == null) {
244 addrs[i] = new InternetAddress(addr.getAddress());
245 } else {
246 addrs[i] = new InternetAddress(addr.getAddress(),
247 addr.getName());
248 }
249 }
250
251 return addrs;
252
253 }
254
255 private String parseCharSetFromMimeType(String type) {
256 int pos;
257 if (type == null || (pos = type.indexOf("charset")) < 0) {
258 return null;
259 }
260 // Assuming mime type in form "text/XXXX; charset=XXXXXX"
261 StringTokenizer token = new StringTokenizer(type.substring(pos), "=; ");
262 token.nextToken(); // Skip 'charset='
263 return token.nextToken();
264 }
265
266 static class SimpleAuthenticator extends Authenticator {
267 private String user = null;
268 private String password = null;
269 public SimpleAuthenticator(String user, String password) {
270 this.user = user;
271 this.password = password;
272 }
273 public PasswordAuthentication getPasswordAuthentication() {
274
275 return new PasswordAuthentication(user, password);
276 }
277 }
278}
279
Note: See TracBrowser for help on using the repository browser.