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.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Date;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Properties;
26
27 import javax.mail.Authenticator;
28 import javax.mail.Message;
29 import javax.mail.MessagingException;
30 import javax.mail.Session;
31 import javax.mail.Store;
32 import javax.mail.Transport;
33 import javax.mail.internet.InternetAddress;
34 import javax.mail.internet.MimeMessage;
35 import javax.mail.internet.MimeMultipart;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public abstract class Email
57 {
58
59
60
61 public static final String SENDER_EMAIL = "sender.email";
62
63 public static final String SENDER_NAME = "sender.name";
64
65 public static final String RECEIVER_EMAIL = "receiver.email";
66
67 public static final String RECEIVER_NAME = "receiver.name";
68
69 public static final String EMAIL_SUBJECT = "email.subject";
70
71 public static final String EMAIL_BODY = "email.body";
72
73 public static final String CONTENT_TYPE = "content.type";
74
75
76 public static final String MAIL_HOST = "mail.host";
77
78 public static final String MAIL_PORT = "mail.smtp.port";
79
80 public static final String MAIL_SMTP_FROM = "mail.smtp.from";
81
82 public static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
83
84 public static final String MAIL_TRANSPORT_PROTOCOL =
85 "mail.transport.protocol";
86
87 public static final String SMTP = "smtp";
88
89 public static final String TEXT_HTML = "text/html";
90
91 public static final String TEXT_PLAIN = "text/plain";
92
93 public static final String ATTACHMENTS = "attachments";
94
95 public static final String FILE_SERVER = "file.server";
96
97 public static final String MAIL_DEBUG = "mail.debug";
98
99
100 public static final String KOI8_R = "koi8-r";
101
102 public static final String ISO_8859_1 = "iso-8859-1";
103
104 public static final String US_ASCII = "us-ascii";
105
106
107 protected MimeMessage message;
108
109
110 protected String charset;
111
112
113 protected InternetAddress fromAddress;
114
115
116 protected String subject;
117
118
119 protected MimeMultipart emailBody;
120
121
122 protected Object content;
123
124
125 protected String contentType;
126
127
128 protected boolean debug;
129
130
131 protected Date sentDate;
132
133
134
135
136
137 protected Authenticator authenticator;
138
139
140
141
142
143 protected String hostName;
144
145
146
147
148
149 protected String smtpPort = "25";
150
151
152 protected List toList = new ArrayList();
153
154
155 protected List ccList = new ArrayList();
156
157
158 protected List bccList = new ArrayList();
159
160
161 protected List replyList = new ArrayList();
162
163
164
165
166
167
168
169 protected String bounceAddress;
170
171
172
173
174
175
176
177
178 protected Map headers = new HashMap();
179
180
181
182
183 protected boolean popBeforeSmtp;
184
185 protected String popHost;
186
187 protected String popUsername;
188
189 protected String popPassword;
190
191
192 private Session session;
193
194
195
196
197
198
199
200 public void setDebug(boolean d)
201 {
202 this.debug = d;
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public void setAuthentication(String userName, String password)
219 {
220 this.authenticator = new DefaultAuthenticator(userName, password);
221 this.setAuthenticator(this.authenticator);
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235 public void setAuthenticator(Authenticator newAuthenticator)
236 {
237 this.authenticator = newAuthenticator;
238 }
239
240
241
242
243
244
245
246 public void setCharset(String newCharset)
247 {
248 this.charset = newCharset;
249 }
250
251
252
253
254
255
256
257 public void setContent(MimeMultipart aMimeMultipart)
258 {
259 this.emailBody = aMimeMultipart;
260 }
261
262
263
264
265
266
267
268
269 public void setContent(Object aObject, String aContentType)
270 {
271 this.content = aObject;
272 if (EmailUtils.isEmpty(aContentType))
273 {
274 this.contentType = null;
275 }
276 else
277 {
278
279 this.contentType = aContentType;
280
281
282 String strMarker = "; charset=";
283 int charsetPos = aContentType.toLowerCase().indexOf(strMarker);
284
285 if (charsetPos != -1)
286 {
287
288 charsetPos += strMarker.length();
289 int intCharsetEnd =
290 aContentType.toLowerCase().indexOf(" ", charsetPos);
291
292 if (intCharsetEnd != -1)
293 {
294 this.charset =
295 aContentType.substring(charsetPos, intCharsetEnd);
296 }
297 else
298 {
299 this.charset = aContentType.substring(charsetPos);
300 }
301 }
302 }
303 }
304
305
306
307
308
309
310
311 public void setHostName(String aHostName)
312 {
313 this.hostName = aHostName;
314 }
315
316
317
318
319
320
321 public void setSmtpPort(int aPortNumber)
322 {
323 if (aPortNumber < 1)
324 {
325 throw new IllegalArgumentException(
326 "Cannot connect to a port number that is less than 1 ( "
327 + aPortNumber
328 + " )");
329 }
330
331 this.smtpPort = Integer.toString(aPortNumber);
332 }
333
334
335
336
337
338
339 public void setMailSession(Session aSession)
340 {
341 this.session = aSession;
342 }
343
344
345
346
347
348
349
350
351 public Session getMailSession() throws EmailException
352 {
353 if (this.session == null)
354 {
355 Properties properties = new Properties(System.getProperties());
356 properties.setProperty(MAIL_TRANSPORT_PROTOCOL, SMTP);
357
358 if (EmailUtils.isEmpty(this.hostName))
359 {
360 this.hostName = properties.getProperty(MAIL_HOST);
361 }
362
363 if (EmailUtils.isEmpty(this.hostName))
364 {
365 throw new EmailException(
366 "Cannot find valid hostname for mail session");
367 }
368
369 properties.setProperty(MAIL_PORT, smtpPort);
370 properties.setProperty(MAIL_HOST, hostName);
371 properties.setProperty(MAIL_DEBUG, String.valueOf(this.debug));
372
373 if (this.authenticator != null)
374 {
375 properties.setProperty(MAIL_SMTP_AUTH, "true");
376 }
377
378 if (this.bounceAddress != null)
379 {
380 properties.setProperty(MAIL_SMTP_FROM, this.bounceAddress);
381 }
382
383
384
385 this.session =
386 Session.getInstance(properties, this.authenticator);
387 }
388 return this.session;
389 }
390
391
392
393
394
395
396
397
398
399 private InternetAddress createInternetAddress(String email, String name)
400 throws EmailException
401 {
402 InternetAddress address = null;
403
404 try
405 {
406
407 if (EmailUtils.isEmpty(name))
408 {
409 name = email;
410 }
411
412
413
414 address = new InternetAddress(email);
415
416 if (EmailUtils.isNotEmpty(this.charset))
417 {
418 address.setPersonal(name, this.charset);
419 }
420 else
421 {
422 address.setPersonal(name);
423 }
424 }
425 catch (Exception e)
426 {
427 throw new EmailException(e);
428 }
429 return address;
430 }
431
432
433
434
435
436
437
438
439
440
441 public Email setFrom(String email)
442 throws EmailException
443 {
444 return setFrom(email, null);
445 }
446
447
448
449
450
451
452
453
454
455
456 public Email setFrom(String email, String name)
457 throws EmailException
458 {
459 this.fromAddress = createInternetAddress(email, name);
460
461 return this;
462 }
463
464
465
466
467
468
469
470
471
472 public Email addTo(String email)
473 throws EmailException
474 {
475 return addTo(email, null);
476 }
477
478
479
480
481
482
483
484
485
486
487 public Email addTo(String email, String name)
488 throws EmailException
489 {
490 this.toList.add(createInternetAddress(email, name));
491 return this;
492 }
493
494
495
496
497
498
499
500
501
502 public Email setTo(Collection aCollection) throws EmailException
503 {
504 if (aCollection == null || aCollection.isEmpty())
505 {
506 throw new EmailException("Address List provided was invalid");
507 }
508
509 this.toList = new ArrayList(aCollection);
510 return this;
511 }
512
513
514
515
516
517
518
519
520
521 public Email addCc(String email)
522 throws EmailException
523 {
524 return this.addCc(email, null);
525 }
526
527
528
529
530
531
532
533
534
535
536 public Email addCc(String email, String name)
537 throws EmailException
538 {
539 this.ccList.add(createInternetAddress(email, name));
540 return this;
541 }
542
543
544
545
546
547
548
549
550
551 public Email setCc(Collection aCollection) throws EmailException
552 {
553 if (aCollection == null || aCollection.isEmpty())
554 {
555 throw new EmailException("Address List provided was invalid");
556 }
557
558 this.ccList = new ArrayList(aCollection);
559 return this;
560 }
561
562
563
564
565
566
567
568
569
570 public Email addBcc(String email)
571 throws EmailException
572 {
573 return this.addBcc(email, null);
574 }
575
576
577
578
579
580
581
582
583
584
585 public Email addBcc(String email, String name)
586 throws EmailException
587 {
588 this.bccList.add(createInternetAddress(email, name));
589 return this;
590 }
591
592
593
594
595
596
597
598
599
600 public Email setBcc(Collection aCollection) throws EmailException
601 {
602 if (aCollection == null || aCollection.isEmpty())
603 {
604 throw new EmailException("Address List provided was invalid");
605 }
606
607 this.bccList = new ArrayList(aCollection);
608 return this;
609 }
610
611
612
613
614
615
616
617
618
619 public Email addReplyTo(String email)
620 throws EmailException
621 {
622 return this.addReplyTo(email, null);
623 }
624
625
626
627
628
629
630
631
632
633
634 public Email addReplyTo(String email, String name)
635 throws EmailException
636 {
637 this.replyList.add(createInternetAddress(email, name));
638 return this;
639 }
640
641
642
643
644
645
646
647
648
649
650
651
652 public void setHeaders(Map map)
653 {
654 Iterator iterKeyBad = map.entrySet().iterator();
655
656 while (iterKeyBad.hasNext())
657 {
658 Map.Entry entry = (Map.Entry) iterKeyBad.next();
659 String strName = (String) entry.getKey();
660 String strValue = (String) entry.getValue();
661
662 if (EmailUtils.isEmpty(strName))
663 {
664 throw new IllegalArgumentException("name can not be null");
665 }
666 if (EmailUtils.isEmpty(strValue))
667 {
668 throw new IllegalArgumentException("value can not be null");
669 }
670 }
671
672
673 this.headers = map;
674 }
675
676
677
678
679
680
681
682
683 public void addHeader(String name, String value)
684 {
685 if (EmailUtils.isEmpty(name))
686 {
687 throw new IllegalArgumentException("name can not be null");
688 }
689 if (EmailUtils.isEmpty(value))
690 {
691 throw new IllegalArgumentException("value can not be null");
692 }
693
694 this.headers.put(name, value);
695 }
696
697
698
699
700
701
702
703
704 public Email setSubject(String aSubject)
705 {
706 this.subject = aSubject;
707 return this;
708 }
709
710
711
712
713
714
715
716
717
718
719
720 public Email setBounceAddress(String email)
721 {
722 this.bounceAddress = email;
723 return this;
724 }
725
726
727
728
729
730
731
732
733
734
735
736 public abstract Email setMsg(String msg) throws EmailException;
737
738
739
740
741
742
743
744 public void buildMimeMessage() throws EmailException
745 {
746 try
747 {
748 this.getMailSession();
749 this.message = new MimeMessage(this.session);
750
751 if (EmailUtils.isNotEmpty(this.subject))
752 {
753 if (EmailUtils.isNotEmpty(this.charset))
754 {
755 this.message.setSubject(this.subject, this.charset);
756 }
757 else
758 {
759 this.message.setSubject(this.subject);
760 }
761 }
762
763
764
765 if (this.content != null)
766 {
767 this.message.setContent(this.content, this.contentType);
768 }
769
770
771 else if (this.emailBody != null)
772 {
773 this.message.setContent(this.emailBody);
774 }
775 else
776 {
777 this.message.setContent("", Email.TEXT_PLAIN);
778 }
779
780 if (this.fromAddress != null)
781 {
782 this.message.setFrom(this.fromAddress);
783 }
784 else
785 {
786 throw new EmailException("Sender address required");
787 }
788
789 if (this.toList.size() + this.ccList.size() + this.bccList.size() == 0)
790 {
791 throw new EmailException(
792 "At least one receiver address required");
793 }
794
795 if (this.toList.size() > 0)
796 {
797 this.message.setRecipients(
798 Message.RecipientType.TO,
799 this.toInternetAddressArray(this.toList));
800 }
801
802 if (this.ccList.size() > 0)
803 {
804 this.message.setRecipients(
805 Message.RecipientType.CC,
806 this.toInternetAddressArray(this.ccList));
807 }
808
809 if (this.bccList.size() > 0)
810 {
811 this.message.setRecipients(
812 Message.RecipientType.BCC,
813 this.toInternetAddressArray(this.bccList));
814 }
815
816 if (this.replyList.size() > 0)
817 {
818 this.message.setReplyTo(
819 this.toInternetAddressArray(this.replyList));
820 }
821
822 if (this.headers.size() > 0)
823 {
824 Iterator iterHeaderKeys = this.headers.keySet().iterator();
825 while (iterHeaderKeys.hasNext())
826 {
827 String name = (String) iterHeaderKeys.next();
828 String value = (String) headers.get(name);
829 this.message.addHeader(name, value);
830 }
831 }
832
833 if (this.message.getSentDate() == null)
834 {
835 this.message.setSentDate(getSentDate());
836 }
837
838 if (this.popBeforeSmtp)
839 {
840 Store store = session.getStore("pop3");
841 store.connect(this.popHost, this.popUsername, this.popPassword);
842 }
843 }
844 catch (MessagingException me)
845 {
846 throw new EmailException(me);
847 }
848 }
849
850
851
852
853
854
855
856 public String sendMimeMessage()
857 throws EmailException
858 {
859 EmailUtils.notNull(this.message, "message");
860
861 try
862 {
863 Transport.send(this.message);
864 return this.message.getMessageID();
865 }
866 catch (Throwable t)
867 {
868 String msg = "Sending the email to the following server failed : "
869 + this.getHostName()
870 + ":"
871 + this.getSmtpPort();
872
873 throw new EmailException(msg, t);
874 }
875 }
876
877
878
879
880
881
882
883 public MimeMessage getMimeMessage()
884 {
885 return this.message;
886 }
887
888
889
890
891
892
893
894
895 public String send() throws EmailException
896 {
897 this.buildMimeMessage();
898 return this.sendMimeMessage();
899 }
900
901
902
903
904
905
906
907
908 public void setSentDate(Date date)
909 {
910 this.sentDate = date;
911 }
912
913
914
915
916
917
918
919 public Date getSentDate()
920 {
921 if (this.sentDate == null)
922 {
923 return new Date();
924 }
925 return this.sentDate;
926 }
927
928
929
930
931
932
933 public String getSubject()
934 {
935 return this.subject;
936 }
937
938
939
940
941
942
943 public InternetAddress getFromAddress()
944 {
945 return this.fromAddress;
946 }
947
948
949
950
951
952
953 public String getHostName()
954 {
955 return this.hostName;
956 }
957
958
959
960
961
962
963 public String getSmtpPort()
964 {
965 return this.smtpPort;
966 }
967
968
969
970
971
972
973
974
975
976 protected InternetAddress[] toInternetAddressArray(List list)
977 {
978 InternetAddress[] ia =
979 (InternetAddress[]) list.toArray(new InternetAddress[list.size()]);
980
981 return ia;
982 }
983
984
985
986
987
988
989
990
991
992
993
994 public void setPopBeforeSmtp(
995 boolean newPopBeforeSmtp,
996 String newPopHost,
997 String newPopUsername,
998 String newPopPassword)
999 {
1000 this.popBeforeSmtp = newPopBeforeSmtp;
1001 this.popHost = newPopHost;
1002 this.popUsername = newPopUsername;
1003 this.popPassword = newPopPassword;
1004 }
1005 }
1006