View Javadoc

1   /*
2    * Copyright 2001-2005 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  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   * The base class for all email messages.  This class sets the
39   * sender's email & name, receiver's email & name, subject, and the
40   * sent date.  Subclasses are responsible for setting the message
41   * body.
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:greg@shwoop.com">Greg Ritter</a>
49   * @author <a href="mailto:unknown">Regis Koenig</a>
50   * @author <a href="mailto:colin.chalmers@maxware.nl">Colin Chalmers</a>
51   * @author <a href="mailto:matthias@wessendorf.net">Matthias Wessendorf</a>
52   * @author <a href="mailto:corey.scott@gmail.com">Corey Scott</a>
53   * @version $Revision: 279295 $ $Date: 2005-09-07 12:56:41 +0200 (Wed, 07 Sep 2005) $
54   * @version $Id: Email.java 279295 2005-09-07 10:56:41Z henning $
55   */
56  public abstract class Email
57  {
58      /** Constants used by Email classes. */
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     /** The email message to send. */
107     protected MimeMessage message;
108 
109     /** The charset to use for this message */
110     protected String charset;
111 
112     /** The Address of the sending party, mandatory */
113     protected InternetAddress fromAddress;
114 
115     /** The Subject  */
116     protected String subject;
117 
118     /** An attachment  */
119     protected MimeMultipart emailBody;
120 
121     /** The content  */
122     protected Object content;
123 
124     /** The content type  */
125     protected String contentType;
126 
127     /** Set session debugging on or off */
128     protected boolean debug;
129 
130     /** Sent date */
131     protected Date sentDate;
132 
133     /**
134      * Instance of an <code>Authenticator</code> object that will be used
135      * when authentication is requested from the mail server.
136      */
137     protected Authenticator authenticator;
138 
139     /**
140      * The hostname of the mail server with which to connect. If null will try
141      * to get property from system.properties. If still null, quit
142      */
143     protected String hostName;
144 
145     /**
146      * The port number of the mail server to connect to.
147      * Defaults to the standard port ( 25 ).
148      */
149     protected String smtpPort = "25";
150 
151     /** List of "to" email adresses */
152     protected List toList = new ArrayList();
153 
154     /** List of "cc" email adresses */
155     protected List ccList = new ArrayList();
156 
157     /** List of "bcc" email adresses */
158     protected List bccList = new ArrayList();
159 
160     /** List of "replyTo" email adresses */
161     protected List replyList = new ArrayList();
162 
163     /**
164      * Address to which undeliverable mail should be sent.
165      * Because this is handled by JavaMail as a String property
166      * in the mail session, this property is of type <code>String</code>
167      * rather than <code>InternetAddress</code>.
168      */
169     protected String bounceAddress;
170 
171     /**
172      * Used to specify the mail headers.  Example:
173      *
174      * X-Mailer: Sendmail, X-Priority: 1( highest )
175      * or  2( high ) 3( normal ) 4( low ) and 5( lowest )
176      * Disposition-Notification-To: user@domain.net
177      */
178     protected Map headers = new HashMap();
179 
180     /**
181      * Used to determine whether to use pop3 before smtp, and if so the settings.
182      */
183     protected boolean popBeforeSmtp;
184     /** the host name of the pop3 server */
185     protected String popHost;
186     /** the user name to log into the pop3 server */
187     protected String popUsername;
188     /** the password to log into the pop3 server */
189     protected String popPassword;
190 
191     /** The Session to mail with */
192     private Session session;
193 
194     /**
195      * Setting to true will enable the display of debug information.
196      *
197      * @param d A boolean.
198      * @since 1.0
199      */
200     public void setDebug(boolean d)
201     {
202         this.debug = d;
203     }
204 
205     /**
206      * Sets the userName and password if authentication is needed.  If this
207      * method is not used, no authentication will be performed.
208      * <p>
209      * This method will create a new instance of
210      * <code>DefaultAuthenticator</code> using the supplied parameters.
211      *
212      * @param userName User name for the SMTP server
213      * @param password password for the SMTP server
214      * @see DefaultAuthenticator
215      * @see #setAuthenticator
216      * @since 1.0
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      * Sets the <code>Authenticator</code> to be used when authentication
226      * is requested from the mail server.
227      * <p>
228      * This method should be used when your outgoing mail server requires
229      * authentication.  Your mail server must also support RFC2554.
230      *
231      * @param newAuthenticator the <code>Authenticator</code> object.
232      * @see Authenticator
233      * @since 1.0
234      */
235     public void setAuthenticator(Authenticator newAuthenticator)
236     {
237         this.authenticator = newAuthenticator;
238     }
239 
240     /**
241      * Set the charset of the message.
242      *
243      * @param newCharset A String.
244      * @since 1.0
245      */
246     public void setCharset(String newCharset)
247     {
248         this.charset = newCharset;
249     }
250 
251     /**
252      * Set the emailBody to a MimeMultiPart
253      *
254      * @param aMimeMultipart aMimeMultipart
255      * @since 1.0
256      */
257     public void setContent(MimeMultipart aMimeMultipart)
258     {
259         this.emailBody = aMimeMultipart;
260     }
261 
262     /**
263      * Set the content & contentType
264      *
265      * @param   aObject aObject
266      * @param   aContentType aContentType
267      * @since 1.0
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             // set the content type
279             this.contentType = aContentType;
280 
281             // set the charset if the input was properly formed
282             String strMarker = "; charset=";
283             int charsetPos = aContentType.toLowerCase().indexOf(strMarker);
284 
285             if (charsetPos != -1)
286             {
287                 // find the next space (after the marker)
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      * Set the hostname of the outgoing mail server
307      *
308      * @param   aHostName aHostName
309      * @since 1.0
310      */
311     public void setHostName(String aHostName)
312     {
313         this.hostName = aHostName;
314     }
315 
316     /**
317      * Set the port number of the outgoing mail server.
318      * @param   aPortNumber aPortNumber
319      * @since 1.0
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      * Supply a mail Session object to use
336      * @param aSession mail session to be used
337      * @since 1.0
338      */
339     public void setMailSession(Session aSession)
340     {
341         this.session = aSession;
342     }
343 
344     /**
345      * Initialise a mailsession object
346      *
347      * @return A Session.
348      * @throws EmailException thrown when host name was not set.
349      * @since 1.0
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             // changed this (back) to getInstance due to security exceptions
384             // caused when testing using maven
385             this.session =
386                 Session.getInstance(properties, this.authenticator);
387         }
388         return this.session;
389     }
390 
391     /**
392      * Creates a InternetAddress.
393      *
394      * @param email An email address.
395      * @param name A name.
396      * @return An internet address.
397      * @throws EmailException Thrown when the address supplied or name were invalid.
398      */
399     private InternetAddress createInternetAddress(String email, String name)
400         throws EmailException
401     {
402         InternetAddress address = null;
403 
404         try
405         {
406             // check name input
407             if (EmailUtils.isEmpty(name))
408             {
409                 name = email;
410             }
411 
412             // Using this instead of new InternetAddress(email, name, [charset]) makes
413             // commons-email usable with javamail 1.2 / J2EE 1.3
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      * Set the FROM field of the email.
435      *
436      * @param email A String.
437      * @return An Email.
438      * @throws EmailException Indicates an invalid email address.
439      * @since 1.0
440      */
441     public Email setFrom(String email)
442         throws EmailException
443     {
444         return setFrom(email, null);
445     }
446 
447     /**
448      * Set the FROM field of the email.
449      *
450      * @param email A String.
451      * @param name A String.
452      * @throws EmailException Indicates an invalid email address.
453      * @return An Email.
454      * @since 1.0
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      * Add a recipient TO to the email.
466      *
467      * @param email A String.
468      * @throws EmailException Indicates an invalid email address.
469      * @return An Email.
470      * @since 1.0
471      */
472     public Email addTo(String email)
473         throws EmailException
474     {
475         return addTo(email, null);
476     }
477 
478     /**
479      * Add a recipient TO to the email.
480      *
481      * @param email A String.
482      * @param name A String.
483      * @throws EmailException Indicates an invalid email address.
484      * @return An Email.
485      * @since 1.0
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      * Set a list of "TO" addresses.
496      *
497      * @param  aCollection collection of InternetAddress objects.
498      * @throws EmailException Indicates an invalid email address.
499      * @return An Email.
500      * @since 1.0
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      * Add a recipient CC to the email.
515      *
516      * @param email A String.
517      * @return An Email.
518      * @throws EmailException Indicates an invalid email address.
519      * @since 1.0
520      */
521     public Email addCc(String email)
522         throws EmailException
523     {
524         return this.addCc(email, null);
525     }
526 
527     /**
528      * Add a recipient CC to the email.
529      *
530      * @param email A String.
531      * @param name A String.
532      * @throws EmailException Indicates an invalid email address.
533      * @return An Email.
534      * @since 1.0
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      * Set a list of "CC" addresses.
545      *
546      * @param aCollection collection of InternetAddress objects.
547      * @return An Email.
548      * @throws EmailException Indicates an invalid email address
549      * @since 1.0.
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      * Add a blind BCC recipient to the email.
564      *
565      * @param email A String.
566      * @return An Email.
567      * @throws EmailException Indicates an invalid email address
568      * @since 1.0
569      */
570     public Email addBcc(String email)
571         throws EmailException
572     {
573         return this.addBcc(email, null);
574     }
575 
576     /**
577      * Add a blind BCC recipient to the email.
578      *
579      * @param email A String.
580      * @param name A String.
581      * @return An Email.
582      * @throws EmailException Indicates an invalid email address
583      * @since 1.0
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      * Set a list of "BCC" addresses
594      *
595      * @param   aCollection collection of InternetAddress objects
596      * @return  An Email.
597      * @throws EmailException Indicates an invalid email address
598      * @since 1.0
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      * Add a reply to address to the email.
613      *
614      * @param email A String.
615      * @return An Email.
616      * @throws EmailException Indicates an invalid email address
617      * @since 1.0
618      */
619     public Email addReplyTo(String email)
620         throws EmailException
621     {
622         return this.addReplyTo(email, null);
623     }
624 
625     /**
626      * Add a reply to address to the email.
627      *
628      * @param email A String.
629      * @param name A String.
630      * @return An Email.
631      * @throws EmailException Indicates an invalid email address
632      * @since 1.0
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      * Used to specify the mail headers.  Example:
644      *
645      * X-Mailer: Sendmail, X-Priority: 1( highest )
646      * or  2( high ) 3( normal ) 4( low ) and 5( lowest )
647      * Disposition-Notification-To: user@domain.net
648      *
649      * @param map A Map.
650      * @since 1.0
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         // all is ok, update headers
673         this.headers = map;
674     }
675 
676     /**
677      * Adds a header ( name, value ) to the headers Map.
678      *
679      * @param name A String with the name.
680      * @param value A String with the value.
681      * @since 1.0
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      * Set the email subject.
699      *
700      * @param aSubject A String.
701      * @return An Email.
702      * @since 1.0
703      */
704     public Email setSubject(String aSubject)
705     {
706         this.subject = aSubject;
707         return this;
708     }
709 
710     /**
711      * Set the "bounce address" - the address to which undeliverable messages
712      * will be returned.  If this value is never set, then the message will be
713      * sent to the address specified with the System property "mail.smtp.from",
714      * or if that value is not set, then to the "from" address.
715      *
716      * @param email A String.
717      * @return An Email.
718      * @since 1.0
719      */
720     public Email setBounceAddress(String email)
721     {
722         this.bounceAddress = email;
723         return this;
724     }
725 
726 
727     /**
728      * Define the content of the mail.  It should be overidden by the
729      * subclasses.
730      *
731      * @param msg A String.
732      * @return An Email.
733      * @throws EmailException generic exception.
734      * @since 1.0
735      */
736     public abstract Email setMsg(String msg) throws EmailException;
737 
738     /**
739      * Build the internal MimeMessage to be sent.
740      *
741      * @throws EmailException if there was an error.
742      * @since 1.0
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             // Start of replacement code
765             if (this.content != null)
766             {
767                 this.message.setContent(this.content, this.contentType);
768             }
769             // end of replacement code
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      * Sends the previously created MimeMessage to the SMTP server.
852      *
853      * @return the message id of the underlying MimeMessage
854      * @throws EmailException the sending failed
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      * Returns the internal MimeMessage. Please not that the
879      * MimeMessage is build by the buildMimeMessage() method.
880      *
881      * @return the MimeMessage
882      */
883     public MimeMessage getMimeMessage()
884     {
885         return this.message;
886     }
887 
888     /**
889      * Sends the email. Internally we build a MimeMessage
890      * which is afterwards sent to the SMTP server.
891      *
892      * @return the message id of the underlying MimeMessage
893      * @throws EmailException the sending failed
894      */
895     public String send() throws EmailException
896     {
897         this.buildMimeMessage();
898         return this.sendMimeMessage();
899     }
900 
901     /**
902      * Sets the sent date for the email.  The sent date will default to the
903      * current date if not explictly set.
904      *
905      * @param date Date to use as the sent date on the email
906      * @since 1.0
907      */
908     public void setSentDate(Date date)
909     {
910         this.sentDate = date;
911     }
912 
913     /**
914      * Gets the sent date for the email.
915      *
916      * @return date to be used as the sent date for the email
917      * @since 1.0
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      * Gets the subject of the email.
930      *
931      * @return email subject
932      */
933     public String getSubject()
934     {
935         return this.subject;
936     }
937 
938     /**
939      * Gets the sender of the email.
940      *
941      * @return from address
942      */
943     public InternetAddress getFromAddress()
944     {
945         return this.fromAddress;
946     }
947 
948     /**
949      * Gets the host name of the SMTP server,
950      *
951      * @return host name
952      */
953     public String getHostName()
954     {
955         return this.hostName;
956     }
957 
958     /**
959      * Gets the listening port of the SMTP server.
960      *
961      * @return smtp port
962      */
963     public String getSmtpPort()
964     {
965         return this.smtpPort;
966     }
967 
968     /**
969      * Utility to copy List of known InternetAddress objects into an
970      * array.
971      *
972      * @param list A List.
973      * @return An InternetAddress[].
974      * @since 1.0
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      * Set details regarding "pop3 before smtp" authentication.
986      *
987      * @param newPopBeforeSmtp Wether or not to log into pop3
988      *      server before sending mail.
989      * @param newPopHost The pop3 host to use.
990      * @param newPopUsername The pop3 username.
991      * @param newPopPassword The pop3 password.
992      * @since 1.0
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