/[classpathx]/mail/source/javax/mail/Message.java
ViewVC logotype

Contents of /mail/source/javax/mail/Message.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations) (download)
Thu Dec 9 17:22:12 2004 UTC (19 years, 5 months ago) by dog
Branch: MAIN
Changes since 1.8: +64 -64 lines
2004-12-08  Chris Burdess  <dog@bluezoo.org>

        * Makefile.am: Fixed relative META-INF.
        * all: Reformatted according to GNU Classpath guidelines.

1 /*
2 * Message.java
3 * Copyright(C) 2002 The Free Software Foundation
4 *
5 * This file is part of GNU JavaMail, a library.
6 *
7 * GNU JavaMail is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 *(at your option) any later version.
11 *
12 * GNU JavaMail is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * As a special exception, if you link this library with other files to
22 * produce an executable, this library does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * This exception does not however invalidate any other reasons why the
25 * executable file might be covered by the GNU General Public License.
26 */
27
28 package javax.mail;
29
30 import java.io.InvalidObjectException;
31 import java.io.ObjectStreamException;
32 import java.io.Serializable;
33 import java.util.Date;
34 import java.util.Enumeration;
35 import javax.mail.search.SearchTerm;
36
37 /**
38 * This class models an email message. This is an abstract class. Subclasses
39 * provide actual implementations.
40 * <p>
41 * Message implements the Part interface. Message contains a set of attributes
42 * and a "content". Messages within a folder also have a set of flags that
43 * describe its state within the folder.
44 * <p>
45 * Message defines some new attributes in addition to those defined in the
46 * Part interface. These attributes specify meta-data for the message - i.e.,
47 * addressing and descriptive information about the message.
48 * <p>
49 * Message objects are obtained either from a Folder or by constructing a new
50 * Message object of the appropriate subclass. Messages that have been received
51 * are normally retrieved from a folder named "INBOX".
52 * <p>
53 * A Message object obtained from a folder is just a lightweight reference to
54 * the actual message. The Message is 'lazily' filled up(on demand) when
55 * each item is requested from the message. Note that certain folder
56 * implementations may return Message objects that are pre-filled with certain
57 * user-specified items. To send a message, an appropriate subclass of
58 * Message(e.g., MimeMessage) is instantiated, the attributes and content
59 * are filled in, and the message is sent using the <code>Transport.send</code>
60 * method.
61 *
62 * @see Part
63 * @author <a href="mailto:dog@gnu.org">Chris Burdess</a>
64 * @version 1.3
65 */
66 public abstract class Message
67 implements Part
68 {
69
70 /**
71 * This inner class defines the types of recipients allowed by the
72 * Message class.
73 * The currently defined types are TO, CC and BCC.
74 * Note that this class only has a protected constructor,
75 * thereby restricting new Recipient types to either this class or
76 * subclasses. This effectively implements an enumeration of the allowed
77 * Recipient types. The following code sample shows how to use this class
78 * to obtain the "TO" recipients from a message.
79 */
80 public static class RecipientType
81 implements Serializable
82 {
83
84 /**
85 * The "To"(primary) recipients.
86 */
87 public static final RecipientType TO = new RecipientType("To");
88
89 /**
90 * The "Cc"(carbon copy) recipients.
91 */
92 public static final RecipientType CC = new RecipientType("Cc");
93
94 /**
95 * The "Bcc"(blind carbon copy) recipients.
96 */
97 public static final RecipientType BCC = new RecipientType("Bcc");
98
99 /**
100 * The type of recipient, usually the name of a corresponding Internet
101 * standard header.
102 */
103 protected String type;
104
105 /**
106 * Constructor for use by subclasses.
107 */
108 protected RecipientType(String type)
109 {
110 this.type = type;
111 }
112
113 /**
114 * When deserializing a RecipientType, we need to make sure to return
115 * only one of the known static final instances defined in this class.
116 * Subclasses must implement their own readResolve method that checks
117 * for their known instances before calling this super method.
118 */
119 protected Object readResolve()
120 throws ObjectStreamException
121 {
122 if (type.equals("To"))
123 {
124 return TO;
125 }
126 if (type.equals("Cc"))
127 {
128 return CC;
129 }
130 if (type.equals("Bcc"))
131 {
132 return BCC;
133 }
134 throw new InvalidObjectException("Unknown RecipientType: " + type);
135 }
136
137 }
138
139 /**
140 * The number of this message within its folder,
141 * or zero if the message was not retrieved from a folder.
142 */
143 protected int msgnum = 0;
144
145 /**
146 * True if this message has been expunged.
147 */
148 protected boolean expunged = false;
149
150 /**
151 * The containing folder, if this message is obtained from a folder
152 */
153 protected Folder folder;
154
155 /**
156 * The Session object for this Message
157 */
158 protected Session session;
159
160 /**
161 * No-arg version of the constructor.
162 */
163 protected Message()
164 {
165 folder = null;
166 session = null;
167 }
168
169 /**
170 * Constructor that takes a Folder and a message number.
171 * Used by Folder implementations.
172 * @param folder containing folder
173 * @param msgnum this message's sequence number within this folder
174 */
175 protected Message(Folder folder, int msgnum)
176 {
177 this.folder = folder;
178 this.msgnum = msgnum;
179 session = folder.store.session;
180 }
181
182 /**
183 * Constructor that takes a Session.
184 * Used for client created Message objects.
185 * @param session A Session object
186 */
187 protected Message(Session session)
188 {
189 folder = null;
190 this.session = session;
191 }
192
193 /**
194 * Returns the "From" attribute.
195 * The "From" attribute contains the identity of the person(s) who
196 * wished this message to be sent.
197 * <p>
198 * In certain implementations, this may be different from the entity that
199 * actually sent the message.
200 * <p>
201 * This method returns null if this attribute is not present in this message.
202 * Returns an empty array if this attribute is present, but contains no
203 * addresses.
204 */
205 public abstract Address[] getFrom()
206 throws MessagingException;
207
208 /**
209 * Set the "From" attribute in this Message.
210 * The value of this attribute is obtained from the property "mail.user".
211 * If this property is absent, the system property "user.name" is used.
212 * @exception IllegalWriteException if the underlying implementation does
213 * not support modification of existing values
214 * @exception IllegalStateException if this message is obtained from a
215 * READ_ONLY folder.
216 */
217 public abstract void setFrom()
218 throws MessagingException;
219
220 /**
221 * Set the "From" attribute in this Message.
222 * @param address the sender
223 * @exception IllegalWriteException if the underlying implementation does
224 * not support modification of existing values
225 * @exception IllegalStateException if this message is obtained from a
226 * READ_ONLY folder.
227 */
228 public abstract void setFrom(Address address)
229 throws MessagingException;
230
231 /**
232 * Add these addresses to the existing "From" attribute
233 * @param addresses - the senders
234 * @exception IllegalWriteException if the underlying implementation does
235 * not support modification of existing values
236 * @exception IllegalStateException if this message is obtained from a
237 * READ_ONLY folder.
238 */
239 public abstract void addFrom(Address[] addresses)
240 throws MessagingException;
241
242 /**
243 * Get all the recipient addresses of the given type.
244 * <p>
245 * This method returns null if the header for the given type is not present
246 * in this message. Returns an empty array if the header is present, but
247 * contains no addresses.
248 * @param type the recipient type
249 */
250 public abstract Address[] getRecipients(RecipientType type)
251 throws MessagingException;
252
253 /**
254 * Get all the recipient addresses for the message.
255 * The default implementation extracts the TO, CC, and BCC recipients
256 * using the getRecipients method.
257 * <p>
258 * This method returns null if none of the recipient headers are present in
259 * this message. Returns an empty array if any recipient header is present,
260 * but contains no addresses.
261 */
262 public Address[] getAllRecipients()
263 throws MessagingException
264 {
265 Address[] to = getRecipients(RecipientType.TO);
266 Address[] cc = getRecipients(RecipientType.CC);
267 Address[] bcc = getRecipients(RecipientType.BCC);
268
269 if (cc == null && bcc == null)
270 return to;
271
272 int count = (to == null ? 0 : to.length) +
273 (cc == null ? 0 : cc.length) +
274 (bcc == null ? 0 : bcc.length);
275 Address[] all = new Address[count];
276 int offset = 0;
277 if (to != null)
278 {
279 System.arraycopy(to, 0, all, offset, to.length);
280 offset += to.length;
281 }
282 if (cc != null)
283 {
284 System.arraycopy(cc, 0, all, offset, cc.length);
285 offset += cc.length;
286 }
287 if (bcc != null)
288 {
289 System.arraycopy(bcc, 0, all, offset, bcc.length);
290 offset += bcc.length;
291 }
292 return all;
293 }
294
295 /**
296 * Set the recipient addresses.
297 * All addresses of the specified type are replaced by the addresses
298 * parameter.
299 * @param type the recipient type
300 * @param addresses the addresses
301 * @exception IllegalWriteException if the underlying implementation
302 * does not support modification of existing values
303 * @exception IllegalStateException if this message is obtained from
304 * a READ_ONLY folder.
305 */
306 public abstract void setRecipients(RecipientType type, Address[] addresses)
307 throws MessagingException;
308
309 /**
310 * Set the recipient address.
311 * All addresses of the specified type are replaced by the address parameter.
312 * <p>
313 * The default implementation uses the setRecipients method.
314 * @exception IllegalWriteException if the underlying implementation
315 * does not support modification of existing values
316 */
317 public void setRecipient(RecipientType type, Address address)
318 throws MessagingException
319 {
320 setRecipients(type, new Address[] { address });
321 }
322
323 /**
324 * Add these recipient addresses to the existing ones of the given type.
325 * @param type the recipient type
326 * @param addresses the addresses
327 * @exception IllegalWriteException if the underlying implementation
328 * does not support modification of existing values
329 * @exception IllegalStateException if this message is obtained from
330 * a READ_ONLY folder.
331 */
332 public abstract void addRecipients(RecipientType type, Address[] addresses)
333 throws MessagingException;
334
335 /**
336 * Add this recipient address to the existing ones of the given type.
337 * <p>
338 * The default implementation uses the addRecipients method.
339 * @exception IllegalWriteException if the underlying implementation
340 * does not support modification of existing values
341 */
342 public void addRecipient(RecipientType type, Address address)
343 throws MessagingException
344 {
345 addRecipients(type, new Address[] { address });
346 }
347
348 /**
349 * Get the addresses to which replies should be directed.
350 * This will usually be the sender of the message, but some messages
351 * may direct replies to a different address.
352 * <p>
353 * The default implementation simply calls the getFrom method.
354 * <p>
355 * This method returns null if the corresponding header is not present.
356 * Returns an empty array if the header is present, but contains no
357 * addresses.
358 */
359 public Address[] getReplyTo()
360 throws MessagingException
361 {
362 return getFrom();
363 }
364
365 /**
366 * Set the addresses to which replies should be directed.
367 *(Normally only a single address will be specified.)
368 * Not all message types allow this to be specified separately from
369 * the sender of the message.
370 * <p>
371 * The default implementation provided here just throws the
372 * MethodNotSupportedException.
373 */
374 public void setReplyTo(Address[] addresses)
375 throws MessagingException
376 {
377 throw new MethodNotSupportedException();
378 }
379
380 /**
381 * Get the subject of this message.
382 */
383 public abstract String getSubject()
384 throws MessagingException;
385
386 /**
387 * Set the subject of this message.
388 * @param subject the subject
389 * @exception IllegalWriteException if the underlying implementation
390 * does not support modification of existing values
391 * @exception IllegalStateException if this message is obtained from
392 * a READ_ONLY folder.
393 */
394 public abstract void setSubject(String subject)
395 throws MessagingException;
396
397 /**
398 * Get the date this message was sent.
399 */
400 public abstract Date getSentDate()
401 throws MessagingException;
402
403 /**
404 * Set the sent date of this message.
405 * @param date the sent date of this message
406 * @exception IllegalWriteException if the underlying implementation
407 * does not support modification of existing values
408 * @exception IllegalStateException if this message is obtained from
409 * a READ_ONLY folder.
410 */
411 public abstract void setSentDate(Date date)
412 throws MessagingException;
413
414 /**
415 * Get the date this message was received.
416 */
417 public abstract Date getReceivedDate()
418 throws MessagingException;
419
420 /**
421 * Returns a Flags object containing the flags for this message.
422 * <p>
423 * Modifying any of the flags in this returned Flags object will not affect
424 * the flags of this message. Use <code>setFlags()</code> to do that.
425 */
426 public abstract Flags getFlags()
427 throws MessagingException;
428
429 /**
430 * Check whether the flag specified in the flag argument is set in this
431 * message.
432 * <p>
433 * The default implementation uses getFlags.
434 * @param flag the flag
435 * @return value of the specified flag for this message
436 */
437 public boolean isSet(Flags.Flag flag)
438 throws MessagingException
439 {
440 return getFlags().contains(flag);
441 }
442
443 /**
444 * Set the specified flags on this message to the specified value.
445 * Note that any flags in this message that are not specified in the
446 * given Flags object are unaffected.
447 * <p>
448 * This will result in a MessageChangedEvent being delivered to any
449 * MessageChangedListener registered on this Message's containing folder.
450 * @param flag Flags object containing the flags to be set
451 * @param set the value to be set
452 * @exception IllegalWriteException if the underlying implementation
453 * does not support modification of existing values
454 * @exception IllegalStateException if this message is obtained from
455 * a READ_ONLY folder.
456 */
457 public abstract void setFlags(Flags flag, boolean set)
458 throws MessagingException;
459
460 /**
461 * Set the specified flag on this message to the specified value.
462 * This will result in a MessageChangedEvent being delivered to any
463 * MessageChangedListener registered on this Message's containing folder.
464 * <p>
465 * The default implementation uses the <code>setFlags</code> method.
466 * @exception IllegalWriteException if the underlying implementation
467 * does not support modification of existing values
468 * @exception IllegalStateException if this message is obtained from
469 * a READ_ONLY folder.
470 */
471 public void setFlag(Flags.Flag flag, boolean set)
472 throws MessagingException
473 {
474 setFlags(new Flags(flag), set);
475 }
476
477 /**
478 * Get the Message number for this Message.
479 * A Message object's message number is the relative position of this
480 * Message in its Folder. Note that the message number for a particular
481 * Message can change during a session if other messages in the Folder
482 * are deleted and expunged.
483 * <p>
484 * Valid message numbers start at 1. Messages that do not belong to any
485 * folder(like newly composed or derived messages) have 0 as their
486 * message number.
487 */
488 public int getMessageNumber()
489 {
490 return msgnum;
491 }
492
493 /**
494 * Set the Message number for this Message.
495 * This method is invoked only by the implementation classes.
496 */
497 protected void setMessageNumber(int msgnum)
498 {
499 this.msgnum = msgnum;
500 }
501
502 /**
503 * Get the folder from which this message was obtained.
504 * If this is a new message or nested message, this method returns null.
505 */
506 public Folder getFolder()
507 {
508 return folder;
509 }
510
511 /**
512 * Checks whether this message is expunged.
513 * All other methods except <code>getMessageNumber()</code> are invalid
514 * on an expunged Message object.
515 * <p>
516 * Messages that are expunged due to an explict expunge() request on the
517 * containing Folder are removed from the Folder immediately. Messages that
518 * are externally expunged by another source are marked "expunged" and return
519 * true for the <code>isExpunged()</code> method, but they are not removed
520 * from the Folder until an explicit <code>expunge()</code> is done on the
521 * Folder.
522 * <p>
523 * See the description of <code>expunge()</code> for more details on
524 * expunge handling.
525 * @see Folder#expunge
526 */
527 public boolean isExpunged()
528 {
529 return expunged;
530 }
531
532 /**
533 * Sets the expunged flag for this Message.
534 * This method is to be used only by the implementation classes.
535 */
536 protected void setExpunged(boolean expunged)
537 {
538 this.expunged = expunged;
539 }
540
541 /**
542 * Get a new Message suitable for a reply to this message.
543 * The new Message will have its attributes and headers set up
544 * appropriately. Note that this new message object will be empty,
545 * that is, it will not have a "content".
546 * These will have to be suitably filled in by the client.
547 * <p>
548 * If <code>replyToAll</code> is set, the new Message will be addressed
549 * to all recipients of this message. Otherwise, the reply will be
550 * addressed to only the sender of this message(using the value of the
551 * <code>getReplyTo</code> method).
552 * <p>
553 * The "Subject" field is filled in with the original subject prefixed with
554 * "Re:"(unless it already starts with "Re:").
555 * <p>
556 * The reply message will use the same session as this message.
557 * @param replyToAll reply should be sent to all recipients of this message
558 */
559 public abstract Message reply(boolean replyToAll)
560 throws MessagingException;
561
562 /**
563 * Save any changes made to this message into the message-store when the
564 * containing folder is closed, if the message is contained in a folder.
565 *(Some implementations may save the changes immediately.)
566 * Update any header fields to be consistent with the changed message
567 * contents. If any part of a message's headers or contents are changed,
568 * <code>saveChanges</code> must be called to ensure that those changes
569 * are permanent. If <code>saveChanges</code> is not called, any such
570 * modifications may or may not be saved, depending on the message store
571 * and folder implementation.
572 * <p>
573 * Messages obtained from folders opened READ_ONLY should not be modified
574 * and <code>saveChanges</code> should not be called on such messages.
575 * @exception IllegalWriteException if the underlying implementation
576 * does not support modification of existing values
577 * @exception IllegalStateException if this message is obtained from
578 * a READ_ONLY folder.
579 */
580 public abstract void saveChanges()
581 throws MessagingException;
582
583 /**
584 * Apply the specified Search criterion to this message.
585 * @param term the Search criterion
586 */
587 public boolean match(SearchTerm term)
588 throws MessagingException
589 {
590 return term.match(this);
591 }
592
593 }

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26