View Javadoc

1   /**
2    * 2008, Digitalis Informatica. All rights reserved. Distribuicao e Gestao de Informatica, Lda. Estrada de Paco de Arcos
3    * num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999 http://www.digitalis.pt
4    */
5   
6   package pt.digitalis.dif.utils.mail;
7   
8   import java.util.Arrays;
9   import java.util.Date;
10  import java.util.HashMap;
11  import java.util.List;
12  import java.util.Map;
13  import java.util.Map.Entry;
14  import java.util.Properties;
15  
16  import javax.activation.DataHandler;
17  import javax.activation.FileDataSource;
18  import javax.mail.Message;
19  import javax.mail.MessagingException;
20  import javax.mail.Multipart;
21  import javax.mail.Session;
22  import javax.mail.Transport;
23  import javax.mail.internet.AddressException;
24  import javax.mail.internet.InternetAddress;
25  import javax.mail.internet.MimeBodyPart;
26  import javax.mail.internet.MimeMessage;
27  import javax.mail.internet.MimeMultipart;
28  
29  import pt.digitalis.dif.ioc.DIFIoCRegistry;
30  import pt.digitalis.dif.utils.logging.DIFLogger;
31  import pt.digitalis.dif.utils.logging.IErrorLogManager;
32  import pt.digitalis.utils.common.StringUtils;
33  
34  /**
35   * The Class MailSender.
36   * 
37   * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a><br/>
38   * @created Feb 28, 2009
39   */
40  public class MailSender {
41  
42      /**
43       * The MailSender singleton instance
44       */
45      protected static MailSender instance;
46  
47      /**
48       * Inspector for the 'instance' attribute.
49       * 
50       * @return the instance value
51       */
52      public static MailSender getInstance()
53      {
54  
55          if (instance == null)
56          {
57              IMailConfiguration mailConfiguration = MailConfiguration.getInstance();
58  
59              instance = new MailSender(mailConfiguration);
60          }
61  
62          return instance;
63      }
64  
65      /**
66       * Modifier for the 'instance' attribute.
67       * 
68       * @param instance
69       *            the new instance value to set
70       */
71      public static void setInstance(MailSender instance)
72      {
73          MailSender.instance = instance;
74      }
75  
76      /** Mail Configuration */
77      private IMailConfiguration configuration = null;
78  
79      /** {@link IErrorLogManager} the error Manager */
80      IErrorLogManager errorLogManager = DIFIoCRegistry.getRegistry().getImplementation(IErrorLogManager.class);
81  
82      /**
83       * MailSender Constructor
84       * 
85       * @param configuration
86       *            the {@link IMailConfiguration}
87       */
88      public MailSender(IMailConfiguration configuration)
89      {
90          this.configuration = configuration;
91      }
92  
93      /**
94       * Inspector for the 'configuration' attribute.
95       * 
96       * @return the configuration value
97       */
98      public IMailConfiguration getConfiguration()
99      {
100         return configuration;
101     }
102 
103     /**
104      * Creates a new mail server session.
105      * 
106      * @return a new Mail session
107      */
108     private Session getMailSession()
109     {
110         Properties props = new Properties();
111         props.setProperty("mail.transport.protocol", "smtp");
112         props.setProperty("mail.store.protocol", "pop3");
113         props.setProperty("mail.host", configuration.getMailServer());
114 
115         if (configuration.getMailServerUsername() != null && !"".equals(configuration.getMailServerUsername()))
116             props.setProperty("mail.user", configuration.getMailServerUsername());
117 
118         if (configuration.getMailServerPassword() != null && !"".equals(configuration.getMailServerPassword()))
119             props.setProperty("mail.smtp.auth", "true");
120         else
121             props.setProperty("mail.smtp.auth", "false");
122 
123         props.setProperty("mail.from", configuration.getDefaultFromAddress());
124 
125         if (configuration.getMailServerPort() != 0)
126             props.setProperty("mail.smtp.port", configuration.getMailServerPort() + "");
127 
128         props.put("mail.debug", configuration.getDebugEnabled());
129 
130         props.put("mail.smtp.ssl.enable", configuration.getUseSSL());
131 
132         if (configuration.getOriginalConfs() != null)
133         {
134             props.putAll(configuration.getOriginalConfs());
135         }
136 
137         DIFLogger.getLogger().debug(props);
138 
139         Session mailSession = Session.getDefaultInstance(props);
140 
141         return mailSession;
142     }
143 
144     /**
145      * Send an email.
146      * 
147      * @param type
148      *            the mail type
149      * @param from
150      *            the sender address
151      * @param to
152      *            the mail destination address field.
153      * @param cc
154      *            the mail CC address field.
155      * @param bcc
156      *            the mail BCC address field.
157      * @param subject
158      *            the mail subject
159      * @param body
160      *            the mail body, in HTML
161      * @param attachments
162      *            the mail attachments. Names will be server paths.
163      * @param images
164      *            the html embedded images. Names will be server paths.
165      * @return T if the mail was sent successfully. F otherwise
166      * @throws AddressException
167      *             when an address is invalid
168      * @throws MessagingException
169      *             when an error occurs when sending the email
170      */
171     public boolean sendEmail(MailType type, String from, String to, String cc, String bcc, String subject, String body,
172             List<String> attachments, Map<String, String> images) throws AddressException, MessagingException
173     {
174         return sendEmail(type, from, to, cc, bcc, subject, body, attachments, images, false);
175     }
176 
177     /**
178      * Send an email.
179      * 
180      * @param type
181      *            the mail type
182      * @param from
183      *            the sender address
184      * @param to
185      *            the mail destination address field.
186      * @param cc
187      *            the mail CC address field.
188      * @param bcc
189      *            the mail BCC address field.
190      * @param subject
191      *            the mail subject
192      * @param body
193      *            the mail body, in HTML
194      * @param attachments
195      *            the mail attachments. Names will be server paths.
196      * @param images
197      *            the html embedded images. Names will be server paths.
198      * @param disableErrorLog
199      * @return T if the mail was sent successfully. F otherwise
200      * @throws MessagingException
201      *             when an error occurs when sending the email
202      */
203     public boolean sendEmail(MailType type, String from, String to, String cc, String bcc, String subject, String body,
204             List<String> attachments, Map<String, String> images, boolean disableErrorLog) throws MessagingException
205     {
206         try
207         {
208             // Mail session
209             Session session = getMailSession();
210 
211             // Create message object
212             Message message = new MimeMessage(session);
213 
214             message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
215 
216             message.setSentDate(new Date());
217             message.setSubject(subject);
218 
219             if (from != null)
220                 message.setFrom(InternetAddress.parse(from)[0]);
221             else
222                 message.setFrom(InternetAddress.parse(configuration.getDefaultFromAddress())[0]);
223 
224             if (cc != null)
225                 message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc, false));
226             if (bcc != null)
227                 message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc, false));
228 
229             if (attachments != null || images != null)
230             {
231                 Multipart multipart = new MimeMultipart();
232 
233                 // Set the email message body...
234                 MimeBodyPart messagePart = new MimeBodyPart();
235 
236                 if (MailType.HTML.equals(type))
237                     messagePart.setContent(body,
238                             "text/html"
239                                     + (StringUtils.isBlank(configuration.getEncoding()) ? "" : "; charset="
240                                             + configuration.getEncoding()));
241                 else
242                     messagePart.setContent(body,
243                             "text/plain"
244                                     + (StringUtils.isBlank(configuration.getEncoding()) ? "" : "; charset="
245                                             + configuration.getEncoding()));
246                 messagePart.setText(body);
247                 multipart.addBodyPart(messagePart);
248 
249                 if (attachments != null)
250                 {
251                     // Set the email attachment files..
252                     for (String attach: attachments)
253                     {
254                         MimeBodyPart attachmentPart = new MimeBodyPart();
255                         attachmentPart.setDataHandler(new DataHandler(new FileDataSource(attach)));
256                         // attachmentPart.setFileName(attach);
257 
258                         multipart.addBodyPart(attachmentPart);
259                     }
260                 }
261 
262                 if (images != null)
263                 {
264                     // Set the email attachment files..
265                     for (Entry<String, String> image: images.entrySet())
266                     {
267                         MimeBodyPart embededImagePart = new MimeBodyPart();
268                         embededImagePart.setDataHandler(new DataHandler(new FileDataSource(image.getValue())));
269                         embededImagePart.setHeader("Content-ID", "<" + image.getKey() + ">");
270 
271                         multipart.addBodyPart(embededImagePart);
272                     }
273                 }
274 
275                 message.setContent(multipart);
276             }
277             else
278             {
279                 if (MailType.HTML.equals(type))
280                 {
281                     MimeMultipart multipart = new MimeMultipart();
282                     MimeBodyPart messagePart;
283 
284                     // Set the email message HTML body...
285                     messagePart = new MimeBodyPart();
286                     messagePart.setContent(body,
287                             "text/html"
288                                     + (StringUtils.isBlank(configuration.getEncoding()) ? "" : "; charset="
289                                             + configuration.getEncoding()));
290                     multipart.addBodyPart(messagePart);
291 
292                     // TODO: Add the code to set a plan text alternative to the HTML content...
293                     // // Set the email message plain text alternative body...
294                     // messagePart = new MimeBodyPart();
295                     // messagePart.setText(body);
296                     // multipart.addBodyPart(messagePart);
297                     // multipart.setSubType("alternative");
298 
299                     // if (!StringUtils.isBlank(configuration.getEncoding()))
300                     // message.setContent(multipart, "charset=ISO-8859-1");
301                     // else
302 
303                     message.setContent(multipart);
304                 }
305                 else
306                 {
307                     message.setContent(body,
308                             "text/plain"
309                                     + (StringUtils.isBlank(configuration.getEncoding()) ? "" : "; charset="
310                                             + configuration.getEncoding()));
311                     message.setText(body);
312                 }
313             }
314 
315             // Send message with or without authentication!
316             Transport tr = session.getTransport("smtp");
317             tr.connect(configuration.getMailServer(), configuration.getMailServerUsername(),
318                     configuration.getMailServerPassword());
319             message.saveChanges();
320             tr.sendMessage(message, message.getAllRecipients());
321             tr.close();
322 
323         }
324         catch (AddressException e)
325         {
326             errorLogManager.logError(MailSender.class.getSimpleName(), "sendMail", e.getMessage());
327             throw e;
328         }
329         catch (MessagingException e)
330         {
331             errorLogManager.logError(MailSender.class.getSimpleName(), "sendMail", e.getMessage());
332             throw e;
333         }
334 
335         return false;
336     }
337 
338     /**
339      * Send an HTML text email.
340      * 
341      * @param to
342      *            the mail destination address field
343      * @param cc
344      *            the mail CC address field.
345      * @param bcc
346      *            the mail BCC address field.
347      * @param subject
348      *            the mail subject
349      * @param body
350      *            the mail body, in HTML
351      * @return T if the mail was sent successfully. F otherwise
352      * @throws AddressException
353      *             when an address is invalid
354      * @throws MessagingException
355      *             when an error occurs when sending the email
356      */
357     public boolean sendHTMLEmail(String to, String cc, String bcc, String subject, String body)
358             throws AddressException, MessagingException
359     {
360         return sendHTMLEmail(to, cc, bcc, subject, body, (List<String>) null, (Map<String, String>) null);
361     }
362 
363     /**
364      * Send an HTML text email.
365      * 
366      * @param to
367      *            the mail destination address field
368      * @param cc
369      *            the mail CC address field.
370      * @param bcc
371      *            the mail BCC address field.
372      * @param subject
373      *            the mail subject
374      * @param body
375      *            the mail body, in HTML
376      * @param attachments
377      *            the mail attachments. Names will be server paths.
378      * @param images
379      *            the html embedded images. Names will be server paths.
380      * @return T if the mail was sent successfully. F otherwise
381      * @throws AddressException
382      *             when an address is invalid
383      * @throws MessagingException
384      *             when an error occurs when sending the email
385      */
386     public boolean sendHTMLEmail(String to, String cc, String bcc, String subject, String body,
387             List<String> attachments, Map<String, String> images) throws AddressException, MessagingException
388     {
389         return sendEmail(MailType.HTML, configuration.getDefaultFromAddress(), to, cc, bcc, subject, body, attachments,
390                 images);
391     }
392 
393     /**
394      * Send an HTML text email.
395      * 
396      * @param to
397      *            the mail destination address field
398      * @param cc
399      *            the mail CC address field.
400      * @param bcc
401      *            the mail BCC address field.
402      * @param subject
403      *            the mail subject
404      * @param body
405      *            the mail body, in HTML
406      * @param attachments
407      *            the mail attachments. Names will be server paths and list should be comma separated
408      * @param images
409      *            the html embedded images. Names will be server paths. Format is: "id=imagePath,id2=imagePath"
410      * @return T if the mail was sent successfully. F otherwise
411      * @throws AddressException
412      *             when an address is invalid
413      * @throws MessagingException
414      *             when an error occurs when sending the email
415      */
416     public boolean sendHTMLEmail(String to, String cc, String bcc, String subject, String body, String attachments,
417             String images) throws AddressException, MessagingException
418     {
419         List<String> attachList = null;
420         Map<String, String> imageMap = null;
421 
422         if (attachments != null)
423             attachList = Arrays.asList(attachments.split(","));
424 
425         if (images != null)
426         {
427             String[] imagePairs = images.split(";");
428 
429             for (String imagePair: imagePairs)
430             {
431                 String[] info = imagePair.split("=");
432                 if (info.length == 2)
433                 {
434                     if (imageMap == null)
435                     {
436                         imageMap = new HashMap<String, String>();
437                     }
438 
439                     imageMap.put(info[0], info[1]);
440                 }
441             }
442         }
443 
444         return sendHTMLEmail(to, cc, bcc, subject, body, attachList, imageMap);
445     }
446 
447     /**
448      * Send an HTML text email.
449      * 
450      * @param to
451      *            the mail destination address field
452      * @param cc
453      *            the mail CC address field.
454      * @param bcc
455      *            the mail BCC address field.
456      * @param subject
457      *            the mail subject
458      * @param body
459      *            the mail body, in HTML
460      * @param attachments
461      *            the mail attachments. Names will be server paths.
462      * @return T if the mail was sent successfully. F otherwise
463      * @throws AddressException
464      *             when an address is invalid
465      * @throws MessagingException
466      *             when an error occurs when sending the email
467      */
468     public boolean sendHTMLEmailWithAttachements(String to, String cc, String bcc, String subject, String body,
469             List<String> attachments) throws AddressException, MessagingException
470     {
471         return sendHTMLEmail(to, cc, bcc, subject, body, attachments, null);
472     }
473 
474     /**
475      * Send an HTML text email.
476      * 
477      * @param to
478      *            the mail destination address field
479      * @param cc
480      *            the mail CC address field.
481      * @param bcc
482      *            the mail BCC address field.
483      * @param subject
484      *            the mail subject
485      * @param body
486      *            the mail body, in HTML
487      * @param attachments
488      *            the mail attachments. Names will be server paths and list should be comma separated
489      * @return T if the mail was sent successfully. F otherwise
490      * @throws AddressException
491      *             when an address is invalid
492      * @throws MessagingException
493      *             when an error occurs when sending the email
494      */
495     public boolean sendHTMLEmailWithAttachements(String to, String cc, String bcc, String subject, String body,
496             String attachments) throws AddressException, MessagingException
497     {
498         List<String> attachList = null;
499 
500         if (attachments != null)
501             attachList = Arrays.asList(attachments.split(","));
502 
503         return sendHTMLEmailWithAttachements(to, cc, bcc, subject, body, attachList);
504     }
505 
506     /**
507      * Send an HTML text email.
508      * 
509      * @param to
510      *            the mail destination address field
511      * @param cc
512      *            the mail CC address field.
513      * @param bcc
514      *            the mail BCC address field.
515      * @param subject
516      *            the mail subject
517      * @param body
518      *            the mail body, in HTML
519      * @param images
520      *            the html embedded images. Names will be server paths.
521      * @return T if the mail was sent successfully. F otherwise
522      * @throws AddressException
523      *             when an address is invalid
524      * @throws MessagingException
525      *             when an error occurs when sending the email
526      */
527     public boolean sendHTMLEmailWithImages(String to, String cc, String bcc, String subject, String body,
528             Map<String, String> images) throws AddressException, MessagingException
529     {
530         return sendHTMLEmail(to, cc, bcc, subject, body, null, images);
531     }
532 
533     /**
534      * Send an HTML text email.
535      * 
536      * @param to
537      *            the mail destination address field
538      * @param cc
539      *            the mail CC address field.
540      * @param bcc
541      *            the mail BCC address field.
542      * @param subject
543      *            the mail subject
544      * @param body
545      *            the mail body, in HTML
546      * @param images
547      *            the html embedded images. Names will be server paths. Format is: "id=imagePath,id2=imagePath"
548      * @return T if the mail was sent successfully. F otherwise
549      * @throws AddressException
550      *             when an address is invalid
551      * @throws MessagingException
552      *             when an error occurs when sending the email
553      */
554     public boolean sendHTMLEmailWithImages(String to, String cc, String bcc, String subject, String body, String images)
555             throws AddressException, MessagingException
556     {
557         List<String> imageList = null;
558 
559         if (images != null)
560             imageList = Arrays.asList(images.split(","));
561 
562         return sendHTMLEmailWithAttachements(to, cc, bcc, subject, body, imageList);
563     }
564 
565     /**
566      * Send a plain text email.
567      * 
568      * @param to
569      *            the mail destination address field
570      * @param cc
571      *            the mail CC address field.
572      * @param bcc
573      *            the mail BCC address field.
574      * @param subject
575      *            the mail subject
576      * @param body
577      *            the mail body, in plain text
578      * @return T if the mail was sent successfully. F otherwise
579      * @throws AddressException
580      *             when an address is invalid
581      * @throws MessagingException
582      *             when an error occurs when sending the email
583      */
584     public boolean sendTextEmail(String to, String cc, String bcc, String subject, String body)
585             throws AddressException, MessagingException
586     {
587         return sendTextEmail(to, cc, bcc, subject, body, (List<String>) null);
588     }
589 
590     /**
591      * Send a plain text email.
592      * 
593      * @param to
594      *            the mail destination address field
595      * @param cc
596      *            the mail CC address field.
597      * @param bcc
598      *            the mail BCC address field.
599      * @param subject
600      *            the mail subject
601      * @param body
602      *            the mail body, in plain text
603      * @param attachments
604      *            the mail attachments. Names will be server paths.
605      * @return T if the mail was sent successfully. F otherwise
606      * @throws AddressException
607      *             when an address is invalid
608      * @throws MessagingException
609      *             when an error occurs when sending the email
610      */
611     public boolean sendTextEmail(String to, String cc, String bcc, String subject, String body, List<String> attachments)
612             throws AddressException, MessagingException
613     {
614         return sendEmail(MailType.PLAIN_TEXT, configuration.getDefaultFromAddress(), to, cc, bcc, subject, body,
615                 attachments, null);
616     }
617 
618     /**
619      * Send a plain text email.
620      * 
621      * @param to
622      *            the mail destination address field
623      * @param cc
624      *            the mail CC address field.
625      * @param bcc
626      *            the mail BCC address field.
627      * @param subject
628      *            the mail subject
629      * @param body
630      *            the mail body, in plain text
631      * @param attachments
632      *            the mail attachments. Names will be server paths and list should be comma separated
633      * @return T if the mail was sent successfully. F otherwise
634      * @throws AddressException
635      *             when an address is invalid
636      * @throws MessagingException
637      *             when an error occurs when sending the email
638      */
639     public boolean sendTextEmail(String to, String cc, String bcc, String subject, String body, String attachments)
640             throws AddressException, MessagingException
641     {
642         List<String> attachList = null;
643 
644         if (attachments != null)
645             attachList = Arrays.asList(attachments.split(","));
646 
647         return sendTextEmail(to, cc, bcc, subject, body, attachList);
648     }
649 
650 }