KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > mail > Message


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21
22 /*
23  * @(#)Message.java 1.38 05/08/29
24  *
25  * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package javax.mail;
29
30 import java.util.Vector JavaDoc;
31 import java.util.Date JavaDoc;
32 import java.util.Properties JavaDoc;
33 import java.io.*;
34 import javax.mail.search.SearchTerm JavaDoc;
35
36 /**
37  * This class models an email message. This is an abstract class.
38  * Subclasses provide actual implementations. <p>
39  *
40  * Message implements the Part interface. Message contains a set of
41  * attributes and a "content". Messages within a folder also have a
42  * set of flags that describe its state within the folder.<p>
43  *
44  * Message defines some new attributes in addition to those defined
45  * in the <code>Part</code> interface. These attributes specify meta-data
46  * for the message - i.e., addressing and descriptive information about
47  * the message. <p>
48  *
49  * Message objects are obtained either from a Folder or by constructing
50  * a new Message object of the appropriate subclass. Messages that have
51  * been received are normally retrieved from a folder named "INBOX". <p>
52  *
53  * A Message object obtained from a folder is just a lightweight
54  * reference to the actual message. The Message is 'lazily' filled
55  * up (on demand) when each item is requested from the message. Note
56  * that certain folder implementations may return Message objects that
57  * are pre-filled with certain user-specified items.
58  
59  * To send a message, an appropriate subclass of Message (e.g.,
60  * MimeMessage) is instantiated, the attributes and content are
61  * filled in, and the message is sent using the <code>Transport.send</code>
62  * method. <p>
63  *
64  * @author John Mani
65  * @author Bill Shannon
66  * @author Max Spivak
67  * @see javax.mail.Part
68  */

69
70 public abstract class Message implements Part JavaDoc {
71
72     /**
73      * The number of this message within its folder, or zero if
74      * the message was not retrieved from a folder.
75      */

76     protected int msgnum = 0;
77
78     /**
79      * True if this message has been expunged.
80      */

81     protected boolean expunged = false;
82
83     /**
84      * The containing folder, if this message is obtained from a folder
85      */

86     protected Folder JavaDoc folder = null;
87
88     /**
89      * The Session object for this Message
90      */

91     protected Session JavaDoc session = null;
92
93     /**
94      * No-arg version of the constructor.
95      */

96     protected Message() { }
97
98     /**
99      * Constructor that takes a Folder and a message number.
100      * Used by Folder implementations.
101      *
102      * @param folder containing folder
103      * @param msgnum this message's sequence number within this folder
104      */

105     protected Message(Folder JavaDoc folder, int msgnum) {
106     this.folder = folder;
107     this.msgnum = msgnum;
108     session = folder.store.session;
109     }
110
111     /**
112      * Constructor that takes a Session. Used for client created
113      * Message objects.
114      *
115      * @param session A Session object
116      */

117     protected Message(Session JavaDoc session) {
118     this.session = session;
119     }
120
121     /**
122      * Returns the "From" attribute. The "From" attribute contains
123      * the identity of the person(s) who wished this message to
124      * be sent. <p>
125      *
126      * In certain implementations, this may be different
127      * from the entity that actually sent the message. <p>
128      *
129      * This method returns <code>null</code> if this attribute
130      * is not present in this message. Returns an empty array if
131      * this attribute is present, but contains no addresses.
132      *
133      * @return array of Address objects
134      * @exception MessagingException
135      */

136     public abstract Address JavaDoc[] getFrom() throws MessagingException JavaDoc;
137
138     /**
139      * Set the "From" attribute in this Message. The value of this
140      * attribute is obtained from the property "mail.user". If this
141      * property is absent, the system property "user.name" is used.
142      *
143      * @exception MessagingException
144      * @exception IllegalWriteException if the underlying
145      * implementation does not support modification
146      * of existing values
147      * @exception IllegalStateException if this message is
148      * obtained from a READ_ONLY folder.
149      */

150     public abstract void setFrom() throws MessagingException JavaDoc;
151
152     /**
153      * Set the "From" attribute in this Message.
154      *
155      * @param address the sender
156      * @exception MessagingException
157      * @exception IllegalWriteException if the underlying
158      * implementation does not support modification
159      * of existing values
160      * @exception IllegalStateException if this message is
161      * obtained from a READ_ONLY folder.
162      */

163     public abstract void setFrom(Address JavaDoc address)
164             throws MessagingException JavaDoc;
165
166     /**
167      * Add these addresses to the existing "From" attribute
168      *
169      * @param addresses the senders
170      * @exception IllegalWriteException if the underlying
171      * implementation does not support modification
172      * of existing values
173      * @exception IllegalStateException if this message is
174      * obtained from a READ_ONLY folder.
175      * @exception MessagingException
176      */

177     public abstract void addFrom(Address JavaDoc[] addresses)
178             throws MessagingException JavaDoc;
179
180     /**
181      * This inner class defines the types of recipients allowed by
182      * the Message class. The currently defined types are TO,
183      * CC and BCC.
184      *
185      * Note that this class only has a protected constructor, thereby
186      * restricting new Recipient types to either this class or subclasses.
187      * This effectively implements an enumeration of the allowed Recipient
188      * types.
189      *
190      * The following code sample shows how to use this class to obtain
191      * the "TO" recipients from a message.
192      * <blockquote><pre>
193      *
194      * Message msg = folder.getMessages(1);
195      * Address[] a = m.getRecipients(Message.RecipientType.TO);
196      *
197      * </pre></blockquote><p>
198      *
199      * @see javax.mail.Message#getRecipients
200      * @see javax.mail.Message#setRecipients
201      * @see javax.mail.Message#addRecipients
202      */

203     public static class RecipientType implements Serializable {
204     /**
205      * The "To" (primary) recipients.
206      */

207     public static final RecipientType TO = new RecipientType("To");
208     /**
209      * The "Cc" (carbon copy) recipients.
210      */

211     public static final RecipientType CC = new RecipientType("Cc");
212     /**
213      * The "Bcc" (blind carbon copy) recipients.
214      */

215     public static final RecipientType BCC = new RecipientType("Bcc");
216
217     /**
218      * The type of recipient, usually the name of a corresponding
219      * Internet standard header.
220      *
221      * @serial
222      */

223     protected String JavaDoc type;
224
225     private static final long serialVersionUID = -7479791750606340008L;
226
227     /**
228      * Constructor for use by subclasses.
229      */

230     protected RecipientType(String JavaDoc type) {
231         this.type = type;
232     }
233
234     /**
235      * When deserializing a RecipientType, we need to make sure to
236      * return only one of the known static final instances defined
237      * in this class. Subclasses must implement their own
238      * <code>readResolve</code> method that checks for their known
239      * instances before calling this super method.
240      */

241     protected Object JavaDoc readResolve() throws ObjectStreamException {
242         if (type.equals("To"))
243         return TO;
244         else if (type.equals("Cc"))
245         return CC;
246         else if (type.equals("Bcc"))
247         return BCC;
248         else
249         throw new InvalidObjectException(
250             "Attempt to resolve unknown RecipientType: " + type);
251     }
252
253     public String JavaDoc toString() {
254         return type;
255     }
256     }
257
258     /**
259      * Get all the recipient addresses of the given type. <p>
260      *
261      * This method returns <code>null</code> if no recipients of
262      * the given type are present in this message. It may return an
263      * empty array if the header is present, but contains no addresses.
264      *
265      * @param type the recipient type
266      * @return array of Address objects
267      * @exception MessagingException
268      * @see Message.RecipientType#TO
269      * @see Message.RecipientType#CC
270      * @see Message.RecipientType#BCC
271      */

272     public abstract Address JavaDoc[] getRecipients(RecipientType type)
273                                 throws MessagingException JavaDoc;
274
275     /**
276      * Get all the recipient addresses for the message.
277      * The default implementation extracts the TO, CC, and BCC
278      * recipients using the <code>getRecipients</code> method. <p>
279      *
280      * This method returns <code>null</code> if none of the recipient
281      * headers are present in this message. It may Return an empty array
282      * if any recipient header is present, but contains no addresses.
283      *
284      * @return array of Address objects
285      * @exception MessagingException
286      * @see Message.RecipientType#TO
287      * @see Message.RecipientType#CC
288      * @see Message.RecipientType#BCC
289      * @see #getRecipients
290      */

291     public Address JavaDoc[] getAllRecipients() throws MessagingException JavaDoc {
292     Address JavaDoc[] to = getRecipients(RecipientType.TO);
293     Address JavaDoc[] cc = getRecipients(RecipientType.CC);
294     Address JavaDoc[] bcc = getRecipients(RecipientType.BCC);
295
296     if (cc == null && bcc == null)
297         return to; // a common case
298

299     int numRecip =
300         (to != null ? to.length : 0) +
301         (cc != null ? cc.length : 0) +
302         (bcc != null ? bcc.length : 0);
303     Address JavaDoc[] addresses = new Address JavaDoc[numRecip];
304     int pos = 0;
305     if (to != null) {
306         System.arraycopy(to, 0, addresses, pos, to.length);
307         pos += to.length;
308     }
309     if (cc != null) {
310         System.arraycopy(cc, 0, addresses, pos, cc.length);
311         pos += cc.length;
312     }
313     if (bcc != null) {
314         System.arraycopy(bcc, 0, addresses, pos, bcc.length);
315         pos += bcc.length;
316     }
317     return addresses;
318     }
319
320     /**
321      * Set the recipient addresses. All addresses of the specified
322      * type are replaced by the addresses parameter.
323      *
324      * @param type the recipient type
325      * @param addresses the addresses
326      * @exception MessagingException
327      * @exception IllegalWriteException if the underlying
328      * implementation does not support modification
329      * of existing values
330      * @exception IllegalStateException if this message is
331      * obtained from a READ_ONLY folder.
332      */

333     public abstract void setRecipients(RecipientType type, Address JavaDoc[] addresses)
334                                 throws MessagingException JavaDoc;
335
336     /**
337      * Set the recipient address. All addresses of the specified
338      * type are replaced by the address parameter. <p>
339      *
340      * The default implementation uses the <code>setRecipients</code> method.
341      *
342      * @param type the recipient type
343      * @param address the address
344      * @exception MessagingException
345      * @exception IllegalWriteException if the underlying
346      * implementation does not support modification
347      * of existing values
348      */

349     public void setRecipient(RecipientType type, Address JavaDoc address)
350                                 throws MessagingException JavaDoc {
351     Address JavaDoc[] a = new Address JavaDoc[1];
352     a[0] = address;
353     setRecipients(type, a);
354     }
355
356     /**
357      * Add these recipient addresses to the existing ones of the given type.
358      *
359      * @param type the recipient type
360      * @param addresses the addresses
361      * @exception MessagingException
362      * @exception IllegalWriteException if the underlying
363      * implementation does not support modification
364      * of existing values
365      * @exception IllegalStateException if this message is
366      * obtained from a READ_ONLY folder.
367      */

368     public abstract void addRecipients(RecipientType type, Address JavaDoc[] addresses)
369                                 throws MessagingException JavaDoc;
370
371     /**
372      * Add this recipient address to the existing ones of the given type. <p>
373      *
374      * The default implementation uses the <code>addRecipients</code> method.
375      *
376      * @param type the recipient type
377      * @param address the address
378      * @exception MessagingException
379      * @exception IllegalWriteException if the underlying
380      * implementation does not support modification
381      * of existing values
382      */

383     public void addRecipient(RecipientType type, Address JavaDoc address)
384                                 throws MessagingException JavaDoc {
385     Address JavaDoc[] a = new Address JavaDoc[1];
386     a[0] = address;
387     addRecipients(type, a);
388     }
389
390     /**
391      * Get the addresses to which replies should be directed.
392      * This will usually be the sender of the message, but
393      * some messages may direct replies to a different address. <p>
394      *
395      * The default implementation simply calls the <code>getFrom</code>
396      * method. <p>
397      *
398      * This method returns <code>null</code> if the corresponding
399      * header is not present. Returns an empty array if the header
400      * is present, but contains no addresses.
401      *
402      * @return addresses to which replies should be directed
403      * @exception MessagingException
404      * @see #getFrom
405      */

406     public Address JavaDoc[] getReplyTo() throws MessagingException JavaDoc {
407         return getFrom();
408     }
409
410     /**
411      * Set the addresses to which replies should be directed.
412      * (Normally only a single address will be specified.)
413      * Not all message types allow this to be specified separately
414      * from the sender of the message. <p>
415      *
416      * The default implementation provided here just throws the
417      * MethodNotSupportedException.
418      *
419      * @param addresses addresses to which replies should be directed
420      * @exception MessagingException
421      * @exception IllegalWriteException if the underlying
422      * implementation does not support modification
423      * of existing values
424      * @exception IllegalStateException if this message is
425      * obtained from a READ_ONLY folder.
426      * @exception MethodNotSupportedException if the underlying
427      * implementation does not support setting this
428      * attribute
429      */

430     public void setReplyTo(Address JavaDoc[] addresses) throws MessagingException JavaDoc {
431     throw new MethodNotSupportedException JavaDoc("setReplyTo not supported");
432     }
433
434     /**
435      * Get the subject of this message.
436      *
437      * @return the subject
438      * @exception MessagingException
439      */

440     public abstract String JavaDoc getSubject() throws MessagingException JavaDoc;
441
442     /**
443      * Set the subject of this message.
444      *
445      * @param subject the subject
446      * @exception MessagingException
447      * @exception IllegalWriteException if the underlying
448      * implementation does not support modification
449      * of existing values
450      * @exception IllegalStateException if this message is
451      * obtained from a READ_ONLY folder.
452      */

453     public abstract void setSubject(String JavaDoc subject)
454             throws MessagingException JavaDoc;
455
456     /**
457      * Get the date this message was sent.
458      *
459      * @return the date this message was sent
460      * @exception MessagingException
461      */

462     public abstract Date JavaDoc getSentDate() throws MessagingException JavaDoc;
463
464     /**
465      * Set the sent date of this message.
466      *
467      * @param date the sent date of this message
468      * @exception MessagingException
469      * @exception IllegalWriteException if the underlying
470      * implementation does not support modification
471      * of existing values
472      * @exception IllegalStateException if this message is
473      * obtained from a READ_ONLY folder.
474      */

475     public abstract void setSentDate(Date JavaDoc date) throws MessagingException JavaDoc;
476
477     /**
478      * Get the date this message was received.
479      *
480      * @return the date this message was received
481      * @exception MessagingException
482      */

483     public abstract Date JavaDoc getReceivedDate() throws MessagingException JavaDoc;
484
485     /**
486      * Returns a <code>Flags</code> object containing the flags for
487      * this message. <p>
488      *
489      * Modifying any of the flags in this returned Flags object will
490      * not affect the flags of this message. Use <code>setFlags()</code>
491      * to do that. <p>
492      *
493      * @return Flags object containing the flags for this message
494      * @see javax.mail.Flags
495      * @see #setFlags
496      * @exception MessagingException
497      */

498     public abstract Flags JavaDoc getFlags() throws MessagingException JavaDoc;
499
500     /**
501      * Check whether the flag specified in the <code>flag</code>
502      * argument is set in this message. <p>
503      *
504      * The default implementation uses <code>getFlags</code>.
505      *
506      * @param flag the flag
507      * @return value of the specified flag for this message
508      * @see javax.mail.Flags.Flag
509      * @see javax.mail.Flags.Flag#ANSWERED
510      * @see javax.mail.Flags.Flag#DELETED
511      * @see javax.mail.Flags.Flag#DRAFT
512      * @see javax.mail.Flags.Flag#FLAGGED
513      * @see javax.mail.Flags.Flag#RECENT
514      * @see javax.mail.Flags.Flag#SEEN
515      * @exception MessagingException
516      */

517     public boolean isSet(Flags.Flag JavaDoc flag) throws MessagingException JavaDoc {
518     return getFlags().contains(flag);
519     }
520
521     /**
522      * Set the specified flags on this message to the specified value.
523      * Note that any flags in this message that are not specified in
524      * the given <code>Flags</code> object are unaffected. <p>
525      *
526      * This will result in a <code>MessageChangedEvent</code> being
527      * delivered to any MessageChangedListener registered on this
528      * Message's containing folder.
529      *
530      * @param flag Flags object containing the flags to be set
531      * @param set the value to be set
532      * @exception MessagingException
533      * @exception IllegalWriteException if the underlying
534      * implementation does not support modification
535      * of existing values.
536      * @exception IllegalStateException if this message is
537      * obtained from a READ_ONLY folder.
538      * @see javax.mail.event.MessageChangedEvent
539      */

540     public abstract void setFlags(Flags JavaDoc flag, boolean set)
541                 throws MessagingException JavaDoc;
542
543     /**
544      * Set the specified flag on this message to the specified value.
545      *
546      * This will result in a <code>MessageChangedEvent</code> being
547      * delivered to any MessageChangedListener registered on this
548      * Message's containing folder. <p>
549      *
550      * The default implementation uses the <code>setFlags</code> method.
551      *
552      * @param flag Flags.Flag object containing the flag to be set
553      * @param set the value to be set
554      * @exception MessagingException
555      * @exception IllegalWriteException if the underlying
556      * implementation does not support modification
557      * of existing values.
558      * @exception IllegalStateException if this message is
559      * obtained from a READ_ONLY folder.
560      * @see javax.mail.event.MessageChangedEvent
561      */

562     public void setFlag(Flags.Flag JavaDoc flag, boolean set)
563                 throws MessagingException JavaDoc {
564     Flags JavaDoc f = new Flags JavaDoc(flag);
565     setFlags(f, set);
566     }
567
568     /**
569      * Get the Message number for this Message.
570      * A Message object's message number is the relative
571      * position of this Message in its Folder. Note that the message
572      * number for a particular Message can change during a session
573      * if other messages in the Folder are deleted and expunged. <p>
574      *
575      * Valid message numbers start at 1. Messages that do not belong
576      * to any folder (like newly composed or derived messages) have 0
577      * as their message number.
578      *
579      * @return the message number
580      */

581     public int getMessageNumber() {
582     return msgnum;
583     }
584
585     /**
586      * Set the Message number for this Message. This method is
587      * invoked only by the implementation classes.
588      */

589     protected void setMessageNumber(int msgnum) {
590     this.msgnum = msgnum;
591     }
592
593     /**
594      * Get the folder from which this message was obtained. If
595      * this is a new message or nested message, this method returns
596      * null.
597      *
598      * @return the containing folder
599      */

600     public Folder JavaDoc getFolder() {
601     return folder;
602     }
603
604     /**
605      * Checks whether this message is expunged. All other methods except
606      * <code>getMessageNumber()</code> are invalid on an expunged
607      * Message object. <p>
608      *
609      * Messages that are expunged due to an explict <code>expunge()</code>
610      * request on the containing Folder are removed from the Folder
611      * immediately. Messages that are externally expunged by another source
612      * are marked "expunged" and return true for the isExpunged() method,
613      * but they are not removed from the Folder until an explicit
614      * <code>expunge()</code> is done on the Folder. <p>
615      *
616      * See the description of <code>expunge()</code> for more details on
617      * expunge handling.
618      *
619      * @see Folder#expunge
620      */

621     public boolean isExpunged() {
622     return expunged;
623     }
624
625     /**
626      * Sets the expunged flag for this Message. This method is to
627      * be used only by the implementation classes.
628      *
629      * @param expunged the expunged flag
630      */

631     protected void setExpunged(boolean expunged) {
632     this.expunged = expunged;
633     }
634
635     /**
636      * Get a new Message suitable for a reply to this message.
637      * The new Message will have its attributes and headers
638      * set up appropriately. Note that this new message object
639      * will be empty, that is, it will <strong>not</strong> have a "content".
640      * These will have to be suitably filled in by the client. <p>
641      *
642      * If <code>replyToAll</code> is set, the new Message will be addressed
643      * to all recipients of this message. Otherwise, the reply will be
644      * addressed to only the sender of this message (using the value
645      * of the <code>getReplyTo</code> method). <p>
646      *
647      * The "Subject" field is filled in with the original subject
648      * prefixed with "Re:" (unless it already starts with "Re:"). <p>
649      *
650      * The reply message will use the same session as this message.
651      *
652      * @param replyToAll reply should be sent to all recipients
653      * of this message
654      * @return the reply Message
655      * @exception MessagingException
656      */

657     public abstract Message JavaDoc reply(boolean replyToAll) throws MessagingException JavaDoc;
658
659     /**
660      * Save any changes made to this message into the message-store
661      * when the containing folder is closed, if the message is contained
662      * in a folder. (Some implementations may save the changes
663      * immediately.) Update any header fields to be consistent with the
664      * changed message contents. If any part of a message's headers or
665      * contents are changed, saveChanges must be called to ensure that
666      * those changes are permanent. If saveChanges is not called, any
667      * such modifications may or may not be saved, depending on the
668      * message store and folder implementation. <p>
669      *
670      * Messages obtained from folders opened READ_ONLY should not be
671      * modified and saveChanges should not be called on such messages.
672      *
673      * @exception MessagingException
674      * @exception IllegalStateException if this message is
675      * obtained from a READ_ONLY folder.
676      * @exception IllegalWriteException if the underlying
677      * implementation does not support modification
678      * of existing values.
679      */

680     public abstract void saveChanges() throws MessagingException JavaDoc;
681
682     /**
683      * Apply the specified Search criterion to this message.
684      *
685      * @param term the Search criterion
686      * @return true if the Message matches this search
687      * criterion, false otherwise.
688      * @exception MessagingException
689      * @see javax.mail.search.SearchTerm
690      */

691     public boolean match(SearchTerm JavaDoc term) throws MessagingException JavaDoc {
692     return term.match(this);
693     }
694 }
695
Popular Tags