1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.mail;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.net.URL;
22
23 import javax.activation.DataHandler;
24 import javax.activation.DataSource;
25 import javax.activation.FileDataSource;
26 import javax.activation.URLDataSource;
27 import javax.mail.BodyPart;
28 import javax.mail.MessagingException;
29 import javax.mail.internet.MimeBodyPart;
30 import javax.mail.internet.MimeMultipart;
31 import javax.mail.internet.MimePart;
32
33 /***
34 * A multipart email.
35 *
36 * <p>This class is used to send multi-part internet email like
37 * messages with attachments.
38 *
39 * <p>To create a multi-part email, call the default constructor and
40 * then you can call setMsg() to set the message and call the
41 * different attach() methods.
42 *
43 * @since 1.0
44 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
45 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
46 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
47 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
48 * @author <a href="mailto:unknown">Regis Koenig</a>
49 * @author <a href="mailto:corey.scott@gmail.com">Corey Scott</a>
50 * @version $Id: MultiPartEmail.java 279285 2005-09-07 09:52:44Z henning $
51 */
52 public class MultiPartEmail extends Email
53 {
54 /*** Body portion of the email. */
55 private MimeMultipart container;
56
57 /*** The message container. */
58 private BodyPart primaryBodyPart = null;
59
60 /*** The MIME subtype. */
61 private String subType;
62
63 /*** Indicates if the message has been initialized */
64 private boolean initialized;
65
66 /*** Indicates if attachments have been added to the message */
67 private boolean boolHasAttachments;
68
69 /***
70 * Set the MIME subtype of the email.
71 *
72 * @param aSubType MIME subtype of the email
73 * @since 1.0
74 */
75 public void setSubType(String aSubType)
76 {
77 this.subType = aSubType;
78 }
79
80 /***
81 * Get the MIME subtype of the email.
82 *
83 * @return MIME subtype of the email
84 * @since 1.0
85 */
86 public String getSubType()
87 {
88 return subType;
89 }
90
91 /***
92 * Add a new part to the email.
93 *
94 * @param partContent The content.
95 * @param partContentType The content type.
96 * @return An Email.
97 * @throws EmailException see javax.mail.internet.MimeBodyPart
98 * for definitions
99 * @since 1.0
100 */
101 public Email addPart(String partContent, String partContentType)
102 throws EmailException
103 {
104 BodyPart bodyPart = createBodyPart();
105 try
106 {
107 bodyPart.setContent(partContent, partContentType);
108 getContainer().addBodyPart(bodyPart);
109 }
110 catch (MessagingException me)
111 {
112 throw new EmailException(me);
113 }
114
115 return this;
116 }
117
118 /***
119 * Add a new part to the email.
120 *
121 * @param multipart The MimeMultipart.
122 * @return An Email.
123 * @throws EmailException see javax.mail.internet.MimeBodyPart
124 * for definitions
125 * @since 1.0
126 */
127 public Email addPart(MimeMultipart multipart) throws EmailException
128 {
129 try
130 {
131 return addPart(multipart, getContainer().getCount());
132 }
133 catch (MessagingException me)
134 {
135 throw new EmailException(me);
136 }
137 }
138
139 /***
140 * Add a new part to the email.
141 *
142 * @param multipart The part to add.
143 * @param index The index to add at.
144 * @return The email.
145 * @throws EmailException An error occured while adding the part.
146 * @since 1.0
147 */
148 public Email addPart(MimeMultipart multipart, int index) throws EmailException
149 {
150 BodyPart bodyPart = createBodyPart();
151 try
152 {
153 bodyPart.setContent(multipart);
154 getContainer().addBodyPart(bodyPart, index);
155 }
156 catch (MessagingException me)
157 {
158 throw new EmailException(me);
159 }
160
161 return this;
162 }
163
164 /***
165 * Initialize the multipart email.
166 * @since 1.0
167 */
168 protected void init()
169 {
170 if (initialized)
171 {
172 throw new IllegalStateException("Already initialized");
173 }
174
175 container = createMimeMultipart();
176 super.setContent(container);
177
178 initialized = true;
179 }
180
181 /***
182 * Set the message of the email.
183 *
184 * @param msg A String.
185 * @return An Email.
186 * @throws EmailException see javax.mail.internet.MimeBodyPart
187 * for definitions
188 * @since 1.0
189 */
190 public Email setMsg(String msg) throws EmailException
191 {
192
193 if (EmailUtils.isEmpty(msg))
194 {
195 throw new EmailException("Invalid message supplied");
196 }
197 try
198 {
199 BodyPart primary = getPrimaryBodyPart();
200
201 if ((primary instanceof MimePart) && EmailUtils.isNotEmpty(charset))
202 {
203 ((MimePart) primary).setText(msg, charset);
204 }
205 else
206 {
207 primary.setText(msg);
208 }
209 }
210 catch (MessagingException me)
211 {
212 throw new EmailException(me);
213 }
214 return this;
215 }
216
217 /***
218 * Builds the actual MimeMessage
219 *
220 * @throws EmailException see javax.mail.internet.MimeBodyPart
221 * for definitions
222 * @since 1.0
223 */
224 public void buildMimeMessage() throws EmailException
225 {
226 try
227 {
228 if (primaryBodyPart != null)
229 {
230
231
232
233
234 BodyPart body = this.getPrimaryBodyPart();
235 try
236 {
237 body.getContent();
238 }
239 catch (IOException e)
240 {
241
242
243 }
244 }
245
246 if (subType != null)
247 {
248 getContainer().setSubType(subType);
249 }
250
251 super.buildMimeMessage();
252 }
253 catch (MessagingException me)
254 {
255 throw new EmailException(me);
256 }
257 }
258
259 /***
260 * Attach an EmailAttachment.
261 *
262 * @param attachment An EmailAttachment.
263 * @return A MultiPartEmail.
264 * @throws EmailException see javax.mail.internet.MimeBodyPart
265 * for definitions
266 * @since 1.0
267 */
268 public MultiPartEmail attach(EmailAttachment attachment)
269 throws EmailException
270 {
271 MultiPartEmail result = null;
272
273 if (attachment == null)
274 {
275 throw new EmailException("Invalid attachment supplied");
276 }
277
278 URL url = attachment.getURL();
279
280 if (url == null)
281 {
282 String fileName = null;
283 try
284 {
285 fileName = attachment.getPath();
286 File file = new File(fileName);
287 if (!file.exists())
288 {
289 throw new IOException(
290 "\"" + fileName + "\" does not exist");
291 }
292 result =
293 attach(
294 new FileDataSource(file),
295 attachment.getName(),
296 attachment.getDescription(),
297 attachment.getDisposition());
298 }
299 catch (Exception e)
300 {
301 throw new EmailException(
302 "Cannot attach file \"" + fileName + "\"",
303 e);
304 }
305 }
306 else
307 {
308 result =
309 attach(
310 url,
311 attachment.getName(),
312 attachment.getDescription(),
313 attachment.getDisposition());
314 }
315
316 return result;
317 }
318
319 /***
320 * Attach a file located by its URL. The disposition of the file
321 * is set to mixed.
322 *
323 * @param url The URL of the file (may be any valid URL).
324 * @param name The name field for the attachment.
325 * @param description A description for the attachment.
326 * @return A MultiPartEmail.
327 * @throws EmailException see javax.mail.internet.MimeBodyPart
328 * for definitions
329 * @since 1.0
330 */
331 public MultiPartEmail attach(URL url, String name, String description)
332 throws EmailException
333 {
334 return attach(url, name, description, EmailAttachment.ATTACHMENT);
335 }
336
337 /***
338 * Attach a file located by its URL.
339 *
340 * @param url The URL of the file (may be any valid URL).
341 * @param name The name field for the attachment.
342 * @param description A description for the attachment.
343 * @param disposition Either mixed or inline.
344 * @return A MultiPartEmail.
345 * @throws EmailException see javax.mail.internet.MimeBodyPart
346 * for definitions
347 * @since 1.0
348 */
349 public MultiPartEmail attach(
350 URL url,
351 String name,
352 String description,
353 String disposition)
354 throws EmailException
355 {
356
357 try
358 {
359 InputStream is = url.openStream();
360 is.close();
361 }
362 catch (IOException e)
363 {
364 throw new EmailException("Invalid URL set");
365 }
366
367 return attach(new URLDataSource(url), name, description, disposition);
368 }
369
370 /***
371 * Attach a file specified as a DataSource interface.
372 *
373 * @param ds A DataSource interface for the file.
374 * @param name The name field for the attachment.
375 * @param description A description for the attachment.
376 * @return A MultiPartEmail.
377 * @throws EmailException see javax.mail.internet.MimeBodyPart
378 * for definitions
379 * @since 1.0
380 */
381 public MultiPartEmail attach(
382 DataSource ds,
383 String name,
384 String description)
385 throws EmailException
386 {
387
388 try
389 {
390 if (ds == null || ds.getInputStream() == null)
391 {
392 throw new EmailException("Invalid Datasource");
393 }
394 }
395 catch (IOException e)
396 {
397 throw new EmailException("Invalid Datasource");
398 }
399
400 return attach(ds, name, description, EmailAttachment.ATTACHMENT);
401 }
402
403 /***
404 * Attach a file specified as a DataSource interface.
405 *
406 * @param ds A DataSource interface for the file.
407 * @param name The name field for the attachment.
408 * @param description A description for the attachment.
409 * @param disposition Either mixed or inline.
410 * @return A MultiPartEmail.
411 * @throws EmailException see javax.mail.internet.MimeBodyPart
412 * for definitions
413 * @since 1.0
414 */
415 public MultiPartEmail attach(
416 DataSource ds,
417 String name,
418 String description,
419 String disposition)
420 throws EmailException
421 {
422 if (EmailUtils.isEmpty(name))
423 {
424 name = ds.getName();
425 }
426 BodyPart bodyPart = createBodyPart();
427 try
428 {
429 getContainer().addBodyPart(bodyPart);
430
431 bodyPart.setDisposition(disposition);
432 bodyPart.setFileName(name);
433 bodyPart.setDescription(description);
434 bodyPart.setDataHandler(new DataHandler(ds));
435 }
436 catch (MessagingException me)
437 {
438 throw new EmailException(me);
439 }
440 setBoolHasAttachments(true);
441
442 return this;
443 }
444
445 /***
446 * Gets first body part of the message.
447 *
448 * @return The primary body part.
449 * @throws MessagingException An error occured while getting the primary body part.
450 * @since 1.0
451 */
452 protected BodyPart getPrimaryBodyPart() throws MessagingException
453 {
454 if (!initialized)
455 {
456 init();
457 }
458
459
460 if (this.primaryBodyPart == null)
461 {
462 primaryBodyPart = createBodyPart();
463 getContainer().addBodyPart(primaryBodyPart, 0);
464 }
465
466 return primaryBodyPart;
467 }
468
469 /***
470 * Gets the message container.
471 *
472 * @return The message container.
473 * @since 1.0
474 */
475 protected MimeMultipart getContainer()
476 {
477 if (!initialized)
478 {
479 init();
480 }
481 return container;
482 }
483
484 /***
485 * Method that can be overridden if you don't
486 * want to create a MimeBodyPart.
487 * @return
488 */
489 protected BodyPart createBodyPart()
490 {
491 BodyPart bodyPart = new MimeBodyPart();
492 return bodyPart;
493 }
494 /***
495 *
496 * @return
497 */
498 protected MimeMultipart createMimeMultipart()
499 {
500 MimeMultipart mmp = new MimeMultipart();
501 return mmp;
502 }
503
504 /***
505 * @return boolHasAttachments
506 * @since 1.0
507 */
508 public boolean isBoolHasAttachments()
509 {
510 return boolHasAttachments;
511 }
512
513 /***
514 * @param b boolHasAttachments
515 * @since 1.0
516 */
517 public void setBoolHasAttachments(boolean b)
518 {
519 boolHasAttachments = b;
520 }
521
522 /***
523 *
524 * @return
525 */
526 protected boolean isInitialized()
527 {
528 return initialized;
529 }
530
531 /***
532 *
533 * @param b
534 */
535 protected void setInitialized(boolean b)
536 {
537 initialized = b;
538 }
539
540 }