~ubuntu-branches/ubuntu/utopic/ant/utopic

« back to all changes in this revision

Viewing changes to src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-05-15 16:19:56 UTC
  • mfrom: (1.3.3) (5.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20130515161956-vd4ht4u68rok767b
Tags: 1.9.1-1
* New upstream release
  - Refreshed the patches
  - Removed patch 0001-detect-classpath-based-JVM (merged upstream)
* Enabled hardening for the -gcj packages
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
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;
21
 
import java.io.InputStream;
22
 
import java.io.IOException;
23
 
import java.io.PrintStream;
24
 
import java.io.OutputStream;
25
 
import java.io.ByteArrayInputStream;
26
 
import java.io.ByteArrayOutputStream;
27
 
import java.io.UnsupportedEncodingException;
28
 
 
29
 
import java.util.Enumeration;
30
 
import java.util.Iterator;
31
 
import java.util.Locale;
32
 
import java.util.Properties;
33
 
import java.util.StringTokenizer;
34
 
import java.util.Vector;
35
 
 
36
 
import java.security.Provider;
37
 
import java.security.Security;
38
 
 
39
 
import javax.activation.DataHandler;
40
 
import javax.activation.FileDataSource;
41
 
 
42
 
import javax.mail.Authenticator;
43
 
import javax.mail.Address;
44
 
import javax.mail.Message;
45
 
import javax.mail.MessagingException;
46
 
import javax.mail.PasswordAuthentication;
47
 
import javax.mail.SendFailedException;
48
 
import javax.mail.Session;
49
 
import javax.mail.Transport;
50
 
import javax.mail.internet.AddressException;
51
 
import javax.mail.internet.InternetAddress;
52
 
import javax.mail.internet.MimeBodyPart;
53
 
import javax.mail.internet.MimeMessage;
54
 
import javax.mail.internet.MimeMultipart;
55
 
 
56
 
import org.apache.tools.ant.BuildException;
57
 
import org.apache.tools.ant.Project;
58
 
 
59
 
/**
60
 
 * Uses the JavaMail classes to send Mime format email.
61
 
 *
62
 
 * @since Ant 1.5
63
 
 */
64
 
public class MimeMailer extends Mailer {
65
 
    private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
66
 
 
67
 
    private static final String GENERIC_ERROR =
68
 
        "Problem while sending mime mail:";
69
 
 
70
 
    /** Default character set */
71
 
    private static final String DEFAULT_CHARSET
72
 
        = System.getProperty("file.encoding");
73
 
 
74
 
    // To work properly with national charsets we have to use
75
 
    // implementation of interface javax.activation.DataSource
76
 
    /**
77
 
     * String data source implementation.
78
 
     * @since Ant 1.6
79
 
     */
80
 
    class StringDataSource implements javax.activation.DataSource {
81
 
        private String data = null;
82
 
        private String type = null;
83
 
        private String charset = null;
84
 
        private ByteArrayOutputStream out;
85
 
 
86
 
        public InputStream getInputStream() throws IOException {
87
 
            if (data == null && out == null) {
88
 
                throw new IOException("No data");
89
 
            }
90
 
            if (out != null) {
91
 
                String encodedOut = out.toString(charset);
92
 
                data = (data != null) ? data.concat(encodedOut) : encodedOut;
93
 
                out = null;
94
 
            }
95
 
            return new ByteArrayInputStream(data.getBytes(charset));
96
 
        }
97
 
 
98
 
        public OutputStream getOutputStream() throws IOException {
99
 
            out = (out == null) ? new ByteArrayOutputStream() : out;
100
 
            return out;
101
 
        }
102
 
 
103
 
        public void setContentType(String type) {
104
 
            this.type = type.toLowerCase(Locale.ENGLISH);
105
 
        }
106
 
 
107
 
        public String getContentType() {
108
 
            if (type != null && type.indexOf("charset") > 0
109
 
                && type.startsWith("text/")) {
110
 
                return type;
111
 
            }
112
 
            // Must be like "text/plain; charset=windows-1251"
113
 
            return new StringBuffer(type != null ? type : "text/plain").append(
114
 
                "; charset=").append(charset).toString();
115
 
        }
116
 
 
117
 
        public String getName() {
118
 
            return "StringDataSource";
119
 
        }
120
 
 
121
 
        public void setCharset(String charset) {
122
 
            this.charset = charset;
123
 
        }
124
 
 
125
 
        public String getCharset() {
126
 
            return charset;
127
 
        }
128
 
    }
129
 
 
130
 
    /**
131
 
     * Send the email.
132
 
     *
133
 
     * @throws BuildException if the email can't be sent.
134
 
     */
135
 
    public void send() {
136
 
        try {
137
 
            Properties props = new Properties();
138
 
 
139
 
            props.put("mail.smtp.host", host);
140
 
            props.put("mail.smtp.port", String.valueOf(port));
141
 
 
142
 
            // Aside, the JDK is clearly unaware of the Scottish
143
 
            // 'session', which involves excessive quantities of
144
 
            // alcohol :-)
145
 
            Session sesh;
146
 
            Authenticator auth = null;
147
 
            if (SSL) {
148
 
                try {
149
 
                    Provider p = (Provider) Class.forName(
150
 
                        "com.sun.net.ssl.internal.ssl.Provider").newInstance();
151
 
                    Security.addProvider(p);
152
 
                } catch (Exception e) {
153
 
                    throw new BuildException("could not instantiate ssl "
154
 
                        + "security provider, check that you have JSSE in "
155
 
                        + "your classpath");
156
 
                }
157
 
                // SMTP provider
158
 
                props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
159
 
                props.put("mail.smtp.socketFactory.fallback", "false");
160
 
                if (isPortExplicitlySpecified()) {
161
 
                    props.put("mail.smtp.socketFactory.port",
162
 
                              String.valueOf(port));
163
 
                }
164
 
            }
165
 
            if (user != null || password != null) {
166
 
                props.put("mail.smtp.auth", "true");
167
 
                auth = new SimpleAuthenticator(user, password);
168
 
            }
169
 
            if (isStartTLSEnabled()) {
170
 
                props.put("mail.smtp.starttls.enable", "true");
171
 
            }
172
 
            sesh = Session.getInstance(props, auth);
173
 
 
174
 
            //create the message
175
 
            MimeMessage msg = new MimeMessage(sesh);
176
 
            MimeMultipart attachments = new MimeMultipart();
177
 
 
178
 
            //set the sender
179
 
            if (from.getName() == null) {
180
 
                msg.setFrom(new InternetAddress(from.getAddress()));
181
 
            } else {
182
 
                msg.setFrom(new InternetAddress(from.getAddress(),
183
 
                    from.getName()));
184
 
            }
185
 
            // set the reply to addresses
186
 
            msg.setReplyTo(internetAddresses(replyToList));
187
 
            msg.setRecipients(Message.RecipientType.TO,
188
 
                internetAddresses(toList));
189
 
            msg.setRecipients(Message.RecipientType.CC,
190
 
                internetAddresses(ccList));
191
 
            msg.setRecipients(Message.RecipientType.BCC,
192
 
                internetAddresses(bccList));
193
 
 
194
 
            // Choosing character set of the mail message
195
 
            // First: looking it from MimeType
196
 
            String charset = parseCharSetFromMimeType(message.getMimeType());
197
 
            if (charset != null) {
198
 
                // Assign/reassign message charset from MimeType
199
 
                message.setCharset(charset);
200
 
            } else {
201
 
                // Next: looking if charset having explicit definition
202
 
                charset = message.getCharset();
203
 
                if (charset == null) {
204
 
                    // Using default
205
 
                    charset = DEFAULT_CHARSET;
206
 
                    message.setCharset(charset);
207
 
                }
208
 
            }
209
 
            // Using javax.activation.DataSource paradigm
210
 
            StringDataSource sds = new StringDataSource();
211
 
            sds.setContentType(message.getMimeType());
212
 
            sds.setCharset(charset);
213
 
 
214
 
            if (subject != null) {
215
 
                msg.setSubject(subject, charset);
216
 
            }
217
 
            msg.addHeader("Date", getDate());
218
 
 
219
 
            if (headers != null) {
220
 
                for (Iterator iter = headers.iterator(); iter.hasNext();) {
221
 
                    Header h = (Header) iter.next();
222
 
                    msg.addHeader(h.getName(), h.getValue());
223
 
                }
224
 
            }
225
 
            PrintStream out = new PrintStream(sds.getOutputStream());
226
 
            message.print(out);
227
 
            out.close();
228
 
 
229
 
            MimeBodyPart textbody = new MimeBodyPart();
230
 
            textbody.setDataHandler(new DataHandler(sds));
231
 
            attachments.addBodyPart(textbody);
232
 
 
233
 
            Enumeration e = files.elements();
234
 
 
235
 
            while (e.hasMoreElements()) {
236
 
                File file = (File) e.nextElement();
237
 
 
238
 
                MimeBodyPart body;
239
 
 
240
 
                body = new MimeBodyPart();
241
 
                if (!file.exists() || !file.canRead()) {
242
 
                    throw new BuildException("File \"" + file.getAbsolutePath()
243
 
                         + "\" does not exist or is not "
244
 
                         + "readable.");
245
 
                }
246
 
                FileDataSource fileData = new FileDataSource(file);
247
 
                DataHandler fileDataHandler = new DataHandler(fileData);
248
 
 
249
 
                body.setDataHandler(fileDataHandler);
250
 
                body.setFileName(file.getName());
251
 
                attachments.addBodyPart(body);
252
 
            }
253
 
            msg.setContent(attachments);
254
 
            try {
255
 
                // Send the message using SMTP, or SMTPS if the host uses SSL
256
 
                Transport transport = sesh.getTransport(SSL ? "smtps" : "smtp");
257
 
                transport.connect(host, user, password);
258
 
                transport.sendMessage(msg, msg.getAllRecipients());
259
 
            } catch (SendFailedException sfe) {
260
 
                if (!shouldIgnoreInvalidRecipients()) {
261
 
                    throw new BuildException(GENERIC_ERROR, sfe);
262
 
                } else if (sfe.getValidSentAddresses() == null
263
 
                           || sfe.getValidSentAddresses().length == 0) {
264
 
                    throw new BuildException("Couldn't reach any recipient",
265
 
                                             sfe);
266
 
                } else {
267
 
                    Address[] invalid = sfe.getInvalidAddresses();
268
 
                    if (invalid == null) {
269
 
                        invalid = new Address[0];
270
 
                    }
271
 
                    for (int i = 0; i < invalid.length; i++) {
272
 
                        didntReach(invalid[i], "invalid", sfe);
273
 
                    }
274
 
                    Address[] validUnsent = sfe.getValidUnsentAddresses();
275
 
                    if (validUnsent == null) {
276
 
                        validUnsent = new Address[0];
277
 
                    }
278
 
                    for (int i = 0; i < validUnsent.length; i++) {
279
 
                        didntReach(validUnsent[i], "valid", sfe);
280
 
                    }
281
 
                }
282
 
            }
283
 
        } catch (MessagingException e) {
284
 
            throw new BuildException(GENERIC_ERROR, e);
285
 
        } catch (IOException e) {
286
 
            throw new BuildException(GENERIC_ERROR, e);
287
 
        }
288
 
    }
289
 
 
290
 
    private static InternetAddress[] internetAddresses(Vector list)
291
 
        throws AddressException, UnsupportedEncodingException {
292
 
        InternetAddress[] addrs = new InternetAddress[list.size()];
293
 
 
294
 
        for (int i = 0; i < list.size(); ++i) {
295
 
            EmailAddress addr = (EmailAddress) list.elementAt(i);
296
 
 
297
 
            String name = addr.getName();
298
 
            addrs[i] = (name == null)
299
 
                ? new InternetAddress(addr.getAddress())
300
 
                : new InternetAddress(addr.getAddress(), name);
301
 
        }
302
 
        return addrs;
303
 
    }
304
 
 
305
 
    private String parseCharSetFromMimeType(String type) {
306
 
        if (type == null) {
307
 
            return null;
308
 
        }
309
 
        int pos = type.indexOf("charset");
310
 
        if (pos < 0) {
311
 
          return null;
312
 
        }
313
 
        // Assuming mime type in form "text/XXXX; charset=XXXXXX"
314
 
        StringTokenizer token = new StringTokenizer(type.substring(pos), "=; ");
315
 
        token.nextToken(); // Skip 'charset='
316
 
        return token.nextToken();
317
 
    }
318
 
 
319
 
    private void didntReach(Address addr, String category,
320
 
                            MessagingException ex) {
321
 
        String msg = "Failed to send mail to " + category + " address "
322
 
            + addr + " because of " + ex.getMessage();
323
 
        if (task != null) {
324
 
            task.log(msg, Project.MSG_WARN);
325
 
        } else {
326
 
            System.err.println(msg);
327
 
        }
328
 
    }
329
 
 
330
 
    static class SimpleAuthenticator extends Authenticator {
331
 
        private String user = null;
332
 
        private String password = null;
333
 
        public SimpleAuthenticator(String user, String password) {
334
 
            this.user = user;
335
 
            this.password = password;
336
 
        }
337
 
        public PasswordAuthentication getPasswordAuthentication() {
338
 
 
339
 
            return new PasswordAuthentication(user, password);
340
 
        }
341
 
    }
342
 
}
343
 
 
 
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;
 
21
import java.io.InputStream;
 
22
import java.io.IOException;
 
23
import java.io.PrintStream;
 
24
import java.io.OutputStream;
 
25
import java.io.ByteArrayInputStream;
 
26
import java.io.ByteArrayOutputStream;
 
27
import java.io.UnsupportedEncodingException;
 
28
 
 
29
import java.util.Enumeration;
 
30
import java.util.Iterator;
 
31
import java.util.Locale;
 
32
import java.util.Properties;
 
33
import java.util.StringTokenizer;
 
34
import java.util.Vector;
 
35
 
 
36
import java.security.Provider;
 
37
import java.security.Security;
 
38
 
 
39
import javax.activation.DataHandler;
 
40
import javax.activation.FileDataSource;
 
41
 
 
42
import javax.mail.Authenticator;
 
43
import javax.mail.Address;
 
44
import javax.mail.Message;
 
45
import javax.mail.MessagingException;
 
46
import javax.mail.PasswordAuthentication;
 
47
import javax.mail.SendFailedException;
 
48
import javax.mail.Session;
 
49
import javax.mail.Transport;
 
50
import javax.mail.internet.AddressException;
 
51
import javax.mail.internet.InternetAddress;
 
52
import javax.mail.internet.MimeBodyPart;
 
53
import javax.mail.internet.MimeMessage;
 
54
import javax.mail.internet.MimeMultipart;
 
55
 
 
56
import org.apache.tools.ant.BuildException;
 
57
import org.apache.tools.ant.Project;
 
58
 
 
59
/**
 
60
 * Uses the JavaMail classes to send Mime format email.
 
61
 *
 
62
 * @since Ant 1.5
 
63
 */
 
64
public class MimeMailer extends Mailer {
 
65
    private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
 
66
 
 
67
    private static final String GENERIC_ERROR =
 
68
        "Problem while sending mime mail:";
 
69
 
 
70
    /** Default character set */
 
71
    private static final String DEFAULT_CHARSET
 
72
        = System.getProperty("file.encoding");
 
73
 
 
74
    // To work properly with national charsets we have to use
 
75
    // implementation of interface javax.activation.DataSource
 
76
    /**
 
77
     * String data source implementation.
 
78
     * @since Ant 1.6
 
79
     */
 
80
    class StringDataSource implements javax.activation.DataSource {
 
81
        private String data = null;
 
82
        private String type = null;
 
83
        private String charset = null;
 
84
        private ByteArrayOutputStream out;
 
85
 
 
86
        public InputStream getInputStream() throws IOException {
 
87
            if (data == null && out == null) {
 
88
                throw new IOException("No data");
 
89
            }
 
90
            if (out != null) {
 
91
                String encodedOut = out.toString(charset);
 
92
                data = (data != null) ? data.concat(encodedOut) : encodedOut;
 
93
                out = null;
 
94
            }
 
95
            return new ByteArrayInputStream(data.getBytes(charset));
 
96
        }
 
97
 
 
98
        public OutputStream getOutputStream() throws IOException {
 
99
            out = (out == null) ? new ByteArrayOutputStream() : out;
 
100
            return out;
 
101
        }
 
102
 
 
103
        public void setContentType(String type) {
 
104
            this.type = type.toLowerCase(Locale.ENGLISH);
 
105
        }
 
106
 
 
107
        public String getContentType() {
 
108
            if (type != null && type.indexOf("charset") > 0
 
109
                && type.startsWith("text/")) {
 
110
                return type;
 
111
            }
 
112
            // Must be like "text/plain; charset=windows-1251"
 
113
            return new StringBuffer(type != null ? type : "text/plain").append(
 
114
                "; charset=").append(charset).toString();
 
115
        }
 
116
 
 
117
        public String getName() {
 
118
            return "StringDataSource";
 
119
        }
 
120
 
 
121
        public void setCharset(String charset) {
 
122
            this.charset = charset;
 
123
        }
 
124
 
 
125
        public String getCharset() {
 
126
            return charset;
 
127
        }
 
128
    }
 
129
 
 
130
    /**
 
131
     * Send the email.
 
132
     *
 
133
     * @throws BuildException if the email can't be sent.
 
134
     */
 
135
    public void send() {
 
136
        try {
 
137
            Properties props = new Properties();
 
138
 
 
139
            props.put("mail.smtp.host", host);
 
140
            props.put("mail.smtp.port", String.valueOf(port));
 
141
 
 
142
            // Aside, the JDK is clearly unaware of the Scottish
 
143
            // 'session', which involves excessive quantities of
 
144
            // alcohol :-)
 
145
            Session sesh;
 
146
            Authenticator auth = null;
 
147
            if (SSL) {
 
148
                try {
 
149
                    Provider p = (Provider) Class.forName(
 
150
                        "com.sun.net.ssl.internal.ssl.Provider").newInstance();
 
151
                    Security.addProvider(p);
 
152
                } catch (Exception e) {
 
153
                    throw new BuildException("could not instantiate ssl "
 
154
                        + "security provider, check that you have JSSE in "
 
155
                        + "your classpath");
 
156
                }
 
157
                // SMTP provider
 
158
                props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
 
159
                props.put("mail.smtp.socketFactory.fallback", "false");
 
160
                if (isPortExplicitlySpecified()) {
 
161
                    props.put("mail.smtp.socketFactory.port",
 
162
                              String.valueOf(port));
 
163
                }
 
164
            }
 
165
            if (user != null || password != null) {
 
166
                props.put("mail.smtp.auth", "true");
 
167
                auth = new SimpleAuthenticator(user, password);
 
168
            }
 
169
            if (isStartTLSEnabled()) {
 
170
                props.put("mail.smtp.starttls.enable", "true");
 
171
            }
 
172
            sesh = Session.getInstance(props, auth);
 
173
 
 
174
            //create the message
 
175
            MimeMessage msg = new MimeMessage(sesh);
 
176
            MimeMultipart attachments = new MimeMultipart();
 
177
 
 
178
            //set the sender
 
179
            if (from.getName() == null) {
 
180
                msg.setFrom(new InternetAddress(from.getAddress()));
 
181
            } else {
 
182
                msg.setFrom(new InternetAddress(from.getAddress(),
 
183
                    from.getName()));
 
184
            }
 
185
            // set the reply to addresses
 
186
            msg.setReplyTo(internetAddresses(replyToList));
 
187
            msg.setRecipients(Message.RecipientType.TO,
 
188
                internetAddresses(toList));
 
189
            msg.setRecipients(Message.RecipientType.CC,
 
190
                internetAddresses(ccList));
 
191
            msg.setRecipients(Message.RecipientType.BCC,
 
192
                internetAddresses(bccList));
 
193
 
 
194
            // Choosing character set of the mail message
 
195
            // First: looking it from MimeType
 
196
            String charset = parseCharSetFromMimeType(message.getMimeType());
 
197
            if (charset != null) {
 
198
                // Assign/reassign message charset from MimeType
 
199
                message.setCharset(charset);
 
200
            } else {
 
201
                // Next: looking if charset having explicit definition
 
202
                charset = message.getCharset();
 
203
                if (charset == null) {
 
204
                    // Using default
 
205
                    charset = DEFAULT_CHARSET;
 
206
                    message.setCharset(charset);
 
207
                }
 
208
            }
 
209
            // Using javax.activation.DataSource paradigm
 
210
            StringDataSource sds = new StringDataSource();
 
211
            sds.setContentType(message.getMimeType());
 
212
            sds.setCharset(charset);
 
213
 
 
214
            if (subject != null) {
 
215
                msg.setSubject(subject, charset);
 
216
            }
 
217
            msg.addHeader("Date", getDate());
 
218
 
 
219
            if (headers != null) {
 
220
                for (Iterator iter = headers.iterator(); iter.hasNext();) {
 
221
                    Header h = (Header) iter.next();
 
222
                    msg.addHeader(h.getName(), h.getValue());
 
223
                }
 
224
            }
 
225
            PrintStream out = new PrintStream(sds.getOutputStream());
 
226
            message.print(out);
 
227
            out.close();
 
228
 
 
229
            MimeBodyPart textbody = new MimeBodyPart();
 
230
            textbody.setDataHandler(new DataHandler(sds));
 
231
            attachments.addBodyPart(textbody);
 
232
 
 
233
            Enumeration e = files.elements();
 
234
 
 
235
            while (e.hasMoreElements()) {
 
236
                File file = (File) e.nextElement();
 
237
 
 
238
                MimeBodyPart body;
 
239
 
 
240
                body = new MimeBodyPart();
 
241
                if (!file.exists() || !file.canRead()) {
 
242
                    throw new BuildException("File \"" + file.getAbsolutePath()
 
243
                         + "\" does not exist or is not "
 
244
                         + "readable.");
 
245
                }
 
246
                FileDataSource fileData = new FileDataSource(file);
 
247
                DataHandler fileDataHandler = new DataHandler(fileData);
 
248
 
 
249
                body.setDataHandler(fileDataHandler);
 
250
                body.setFileName(file.getName());
 
251
                attachments.addBodyPart(body);
 
252
            }
 
253
            msg.setContent(attachments);
 
254
            try {
 
255
                // Send the message using SMTP, or SMTPS if the host uses SSL
 
256
                Transport transport = sesh.getTransport(SSL ? "smtps" : "smtp");
 
257
                transport.connect(host, user, password);
 
258
                transport.sendMessage(msg, msg.getAllRecipients());
 
259
            } catch (SendFailedException sfe) {
 
260
                if (!shouldIgnoreInvalidRecipients()) {
 
261
                    throw new BuildException(GENERIC_ERROR, sfe);
 
262
                } else if (sfe.getValidSentAddresses() == null
 
263
                           || sfe.getValidSentAddresses().length == 0) {
 
264
                    throw new BuildException("Couldn't reach any recipient",
 
265
                                             sfe);
 
266
                } else {
 
267
                    Address[] invalid = sfe.getInvalidAddresses();
 
268
                    if (invalid == null) {
 
269
                        invalid = new Address[0];
 
270
                    }
 
271
                    for (int i = 0; i < invalid.length; i++) {
 
272
                        didntReach(invalid[i], "invalid", sfe);
 
273
                    }
 
274
                    Address[] validUnsent = sfe.getValidUnsentAddresses();
 
275
                    if (validUnsent == null) {
 
276
                        validUnsent = new Address[0];
 
277
                    }
 
278
                    for (int i = 0; i < validUnsent.length; i++) {
 
279
                        didntReach(validUnsent[i], "valid", sfe);
 
280
                    }
 
281
                }
 
282
            }
 
283
        } catch (MessagingException e) {
 
284
            throw new BuildException(GENERIC_ERROR, e);
 
285
        } catch (IOException e) {
 
286
            throw new BuildException(GENERIC_ERROR, e);
 
287
        }
 
288
    }
 
289
 
 
290
    private static InternetAddress[] internetAddresses(Vector list)
 
291
        throws AddressException, UnsupportedEncodingException {
 
292
        final int size = list.size();
 
293
        InternetAddress[] addrs = new InternetAddress[size];
 
294
 
 
295
        for (int i = 0; i < size; ++i) {
 
296
            EmailAddress addr = (EmailAddress) list.elementAt(i);
 
297
 
 
298
            String name = addr.getName();
 
299
            addrs[i] = (name == null)
 
300
                ? new InternetAddress(addr.getAddress())
 
301
                : new InternetAddress(addr.getAddress(), name);
 
302
        }
 
303
        return addrs;
 
304
    }
 
305
 
 
306
    private String parseCharSetFromMimeType(String type) {
 
307
        if (type == null) {
 
308
            return null;
 
309
        }
 
310
        int pos = type.indexOf("charset");
 
311
        if (pos < 0) {
 
312
          return null;
 
313
        }
 
314
        // Assuming mime type in form "text/XXXX; charset=XXXXXX"
 
315
        StringTokenizer token = new StringTokenizer(type.substring(pos), "=; ");
 
316
        token.nextToken(); // Skip 'charset='
 
317
        return token.nextToken();
 
318
    }
 
319
 
 
320
    private void didntReach(Address addr, String category,
 
321
                            MessagingException ex) {
 
322
        String msg = "Failed to send mail to " + category + " address "
 
323
            + addr + " because of " + ex.getMessage();
 
324
        if (task != null) {
 
325
            task.log(msg, Project.MSG_WARN);
 
326
        } else {
 
327
            System.err.println(msg);
 
328
        }
 
329
    }
 
330
 
 
331
    static class SimpleAuthenticator extends Authenticator {
 
332
        private String user = null;
 
333
        private String password = null;
 
334
        public SimpleAuthenticator(String user, String password) {
 
335
            this.user = user;
 
336
            this.password = password;
 
337
        }
 
338
        public PasswordAuthentication getPasswordAuthentication() {
 
339
 
 
340
            return new PasswordAuthentication(user, password);
 
341
        }
 
342
    }
 
343
}
 
344