Skip to content

Package: Message$RecipientType

Message$RecipientType

nameinstructionbranchcomplexitylinemethod
Message.RecipientType(String)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
readResolve()
M: 34 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 16 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
toString()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package jakarta.mail;
18:
19: import jakarta.mail.search.SearchTerm;
20:
21: import java.io.InvalidObjectException;
22: import java.io.ObjectStreamException;
23: import java.io.Serializable;
24: import java.util.Date;
25:
26: /**
27: * This class models an email message. This is an abstract class.
28: * Subclasses provide actual implementations. <p>
29: *
30: * Message implements the Part interface. Message contains a set of
31: * attributes and a "content". Messages within a folder also have a
32: * set of flags that describe its state within the folder.<p>
33: *
34: * Message defines some new attributes in addition to those defined
35: * in the <code>Part</code> interface. These attributes specify meta-data
36: * for the message - i.e., addressing and descriptive information about
37: * the message. <p>
38: *
39: * Message objects are obtained either from a Folder or by constructing
40: * a new Message object of the appropriate subclass. Messages that have
41: * been received are normally retrieved from a folder named "INBOX". <p>
42: *
43: * A Message object obtained from a folder is just a lightweight
44: * reference to the actual message. The Message is 'lazily' filled
45: * up (on demand) when each item is requested from the message. Note
46: * that certain folder implementations may return Message objects that
47: * are pre-filled with certain user-specified items.
48: *
49: * To send a message, an appropriate subclass of Message (e.g.,
50: * MimeMessage) is instantiated, the attributes and content are
51: * filled in, and the message is sent using the <code>Transport.send</code>
52: * method.
53: *
54: * @author John Mani
55: * @author Bill Shannon
56: * @author Max Spivak
57: * @see jakarta.mail.Part
58: */
59:
60: public abstract class Message implements Part {
61:
62: /**
63: * The number of this message within its folder, or zero if
64: * the message was not retrieved from a folder.
65: */
66: protected int msgnum = 0;
67:
68: /**
69: * True if this message has been expunged.
70: */
71: protected boolean expunged = false;
72:
73: /**
74: * The containing folder, if this message is obtained from a folder
75: */
76: protected Folder folder = null;
77:
78: /**
79: * The Session object for this Message
80: */
81: protected Session session = null;
82:
83: /**
84: * No-arg version of the constructor.
85: */
86: protected Message() {
87: }
88:
89: /**
90: * Constructor that takes a Folder and a message number.
91: * Used by Folder implementations.
92: *
93: * @param folder containing folder
94: * @param msgnum this message's sequence number within this folder
95: */
96: protected Message(Folder folder, int msgnum) {
97: this.folder = folder;
98: this.msgnum = msgnum;
99: session = folder.store.session;
100: }
101:
102: /**
103: * Constructor that takes a Session. Used for client created
104: * Message objects.
105: *
106: * @param session A Session object
107: */
108: protected Message(Session session) {
109: this.session = session;
110: }
111:
112: /**
113: * Return the Session used when this message was created.
114: *
115: * @return the message's Session
116: * @since JavaMail 1.5
117: */
118: public Session getSession() {
119: return session;
120: }
121:
122: /**
123: * Returns the "From" attribute. The "From" attribute contains
124: * the identity of the person(s) who wished this message to
125: * be sent. <p>
126: *
127: * In certain implementations, this may be different
128: * from the entity that actually sent the message. <p>
129: *
130: * This method returns <code>null</code> if this attribute
131: * is not present in this message. Returns an empty array if
132: * this attribute is present, but contains no addresses.
133: *
134: * @return array of Address objects
135: * @throws MessagingException for failures
136: */
137: public abstract Address[] getFrom() throws MessagingException;
138:
139: /**
140: * Set the "From" attribute in this Message. The value of this
141: * attribute is obtained from the property "mail.user". If this
142: * property is absent, the system property "user.name" is used.
143: *
144: * @throws IllegalWriteException if the underlying
145: * implementation does not support modification
146: * of existing values
147: * @throws IllegalStateException if this message is
148: * obtained from a READ_ONLY folder.
149: * @throws MessagingException for other failures
150: */
151: public abstract void setFrom() throws MessagingException;
152:
153: /**
154: * Set the "From" attribute in this Message.
155: *
156: * @param address the sender
157: * @throws IllegalWriteException if the underlying
158: * implementation does not support modification
159: * of existing values
160: * @throws IllegalStateException if this message is
161: * obtained from a READ_ONLY folder.
162: * @throws MessagingException for other failures
163: */
164: public abstract void setFrom(Address address)
165: throws MessagingException;
166:
167: /**
168: * Add these addresses to the existing "From" attribute
169: *
170: * @param addresses the senders
171: * @throws IllegalWriteException if the underlying
172: * implementation does not support modification
173: * of existing values
174: * @throws IllegalStateException if this message is
175: * obtained from a READ_ONLY folder.
176: * @throws MessagingException for other failures
177: */
178: public abstract void addFrom(Address[] addresses)
179: throws MessagingException;
180:
181: /**
182: * This inner class defines the types of recipients allowed by
183: * the Message class. The currently defined types are TO,
184: * CC and BCC.
185: *
186: * Note that this class only has a protected constructor, thereby
187: * restricting new Recipient types to either this class or subclasses.
188: * This effectively implements an enumeration of the allowed Recipient
189: * types.
190: *
191: * The following code sample shows how to use this class to obtain
192: * the "TO" recipients from a message.
193: * <blockquote><pre>
194: *
195: * Message msg = folder.getMessages(1);
196: * Address[] a = m.getRecipients(Message.RecipientType.TO);
197: *
198: * </pre></blockquote>
199: *
200: * @see jakarta.mail.Message#getRecipients
201: * @see jakarta.mail.Message#setRecipients
202: * @see jakarta.mail.Message#addRecipients
203: */
204: public static class RecipientType implements Serializable {
205: /**
206: * The "To" (primary) recipients.
207: */
208: public static final RecipientType TO = new RecipientType("To");
209: /**
210: * The "Cc" (carbon copy) recipients.
211: */
212: public static final RecipientType CC = new RecipientType("Cc");
213: /**
214: * The "Bcc" (blind carbon copy) recipients.
215: */
216: public static final RecipientType BCC = new RecipientType("Bcc");
217:
218: /**
219: * The type of recipient, usually the name of a corresponding
220: * Internet standard header.
221: *
222: * @serial
223: */
224: protected String type;
225:
226: private static final long serialVersionUID = -7479791750606340008L;
227:
228: /**
229: * Constructor for use by subclasses.
230: *
231: * @param type the recipient type
232: */
233: protected RecipientType(String type) {
234: this.type = type;
235: }
236:
237: /**
238: * When deserializing a RecipientType, we need to make sure to
239: * return only one of the known static final instances defined
240: * in this class. Subclasses must implement their own
241: * <code>readResolve</code> method that checks for their known
242: * instances before calling this super method.
243: *
244: * @return the RecipientType object instance
245: * @throws ObjectStreamException for object stream errors
246: */
247: protected Object readResolve() throws ObjectStreamException {
248:• if (type.equals("To"))
249: return TO;
250:• else if (type.equals("Cc"))
251: return CC;
252:• else if (type.equals("Bcc"))
253: return BCC;
254: else
255: throw new InvalidObjectException(
256: "Attempt to resolve unknown RecipientType: " + type);
257: }
258:
259: @Override
260: public String toString() {
261: return type;
262: }
263: }
264:
265: /**
266: * Get all the recipient addresses of the given type. <p>
267: *
268: * This method returns <code>null</code> if no recipients of
269: * the given type are present in this message. It may return an
270: * empty array if the header is present, but contains no addresses.
271: *
272: * @param type the recipient type
273: * @return array of Address objects
274: * @throws MessagingException for failures
275: * @see Message.RecipientType#TO
276: * @see Message.RecipientType#CC
277: * @see Message.RecipientType#BCC
278: */
279: public abstract Address[] getRecipients(RecipientType type)
280: throws MessagingException;
281:
282: /**
283: * Get all the recipient addresses for the message.
284: * The default implementation extracts the TO, CC, and BCC
285: * recipients using the <code>getRecipients</code> method. <p>
286: *
287: * This method returns <code>null</code> if none of the recipient
288: * headers are present in this message. It may Return an empty array
289: * if any recipient header is present, but contains no addresses.
290: *
291: * @return array of Address objects
292: * @throws MessagingException for failures
293: * @see Message.RecipientType#TO
294: * @see Message.RecipientType#CC
295: * @see Message.RecipientType#BCC
296: * @see #getRecipients
297: */
298: public Address[] getAllRecipients() throws MessagingException {
299: Address[] to = getRecipients(RecipientType.TO);
300: Address[] cc = getRecipients(RecipientType.CC);
301: Address[] bcc = getRecipients(RecipientType.BCC);
302:
303: if (cc == null && bcc == null)
304: return to; // a common case
305:
306: int numRecip =
307: (to != null ? to.length : 0) +
308: (cc != null ? cc.length : 0) +
309: (bcc != null ? bcc.length : 0);
310: Address[] addresses = new Address[numRecip];
311: int pos = 0;
312: if (to != null) {
313: System.arraycopy(to, 0, addresses, pos, to.length);
314: pos += to.length;
315: }
316: if (cc != null) {
317: System.arraycopy(cc, 0, addresses, pos, cc.length);
318: pos += cc.length;
319: }
320: if (bcc != null) {
321: System.arraycopy(bcc, 0, addresses, pos, bcc.length);
322: // pos += bcc.length;
323: }
324: return addresses;
325: }
326:
327: /**
328: * Set the recipient addresses. All addresses of the specified
329: * type are replaced by the addresses parameter.
330: *
331: * @param type the recipient type
332: * @param addresses the addresses
333: * @throws IllegalWriteException if the underlying
334: * implementation does not support modification
335: * of existing values
336: * @throws IllegalStateException if this message is
337: * obtained from a READ_ONLY folder.
338: * @throws MessagingException for other failures
339: */
340: public abstract void setRecipients(RecipientType type, Address[] addresses)
341: throws MessagingException;
342:
343: /**
344: * Set the recipient address. All addresses of the specified
345: * type are replaced by the address parameter. <p>
346: *
347: * The default implementation uses the <code>setRecipients</code> method.
348: *
349: * @param type the recipient type
350: * @param address the address
351: * @throws IllegalWriteException if the underlying
352: * implementation does not support modification
353: * of existing values
354: * @throws MessagingException for other failures
355: */
356: public void setRecipient(RecipientType type, Address address)
357: throws MessagingException {
358: if (address == null)
359: setRecipients(type, null);
360: else {
361: Address[] a = new Address[1];
362: a[0] = address;
363: setRecipients(type, a);
364: }
365: }
366:
367: /**
368: * Add these recipient addresses to the existing ones of the given type.
369: *
370: * @param type the recipient type
371: * @param addresses the addresses
372: * @throws IllegalWriteException if the underlying
373: * implementation does not support modification
374: * of existing values
375: * @throws IllegalStateException if this message is
376: * obtained from a READ_ONLY folder.
377: * @throws MessagingException for other failures
378: */
379: public abstract void addRecipients(RecipientType type, Address[] addresses)
380: throws MessagingException;
381:
382: /**
383: * Add this recipient address to the existing ones of the given type. <p>
384: *
385: * The default implementation uses the <code>addRecipients</code> method.
386: *
387: * @param type the recipient type
388: * @param address the address
389: * @throws IllegalWriteException if the underlying
390: * implementation does not support modification
391: * of existing values
392: * @throws MessagingException for other failures
393: */
394: public void addRecipient(RecipientType type, Address address)
395: throws MessagingException {
396: Address[] a = new Address[1];
397: a[0] = address;
398: addRecipients(type, a);
399: }
400:
401: /**
402: * Get the addresses to which replies should be directed.
403: * This will usually be the sender of the message, but
404: * some messages may direct replies to a different address. <p>
405: *
406: * The default implementation simply calls the <code>getFrom</code>
407: * method. <p>
408: *
409: * This method returns <code>null</code> if the corresponding
410: * header is not present. Returns an empty array if the header
411: * is present, but contains no addresses.
412: *
413: * @return addresses to which replies should be directed
414: * @throws MessagingException for failures
415: * @see #getFrom
416: */
417: public Address[] getReplyTo() throws MessagingException {
418: return getFrom();
419: }
420:
421: /**
422: * Set the addresses to which replies should be directed.
423: * (Normally only a single address will be specified.)
424: * Not all message types allow this to be specified separately
425: * from the sender of the message. <p>
426: *
427: * The default implementation provided here just throws the
428: * MethodNotSupportedException.
429: *
430: * @param addresses addresses to which replies should be directed
431: * @throws IllegalWriteException if the underlying
432: * implementation does not support modification
433: * of existing values
434: * @throws IllegalStateException if this message is
435: * obtained from a READ_ONLY folder.
436: * @throws MethodNotSupportedException if the underlying
437: * implementation does not support setting this
438: * attribute
439: * @throws MessagingException for other failures
440: */
441: public void setReplyTo(Address[] addresses) throws MessagingException {
442: throw new MethodNotSupportedException("setReplyTo not supported");
443: }
444:
445: /**
446: * Get the subject of this message.
447: *
448: * @return the subject
449: * @throws MessagingException for failures
450: */
451: public abstract String getSubject() throws MessagingException;
452:
453: /**
454: * Set the subject of this message.
455: *
456: * @param subject the subject
457: * @throws IllegalWriteException if the underlying
458: * implementation does not support modification
459: * of existing values
460: * @throws IllegalStateException if this message is
461: * obtained from a READ_ONLY folder.
462: * @throws MessagingException for other failures
463: */
464: public abstract void setSubject(String subject)
465: throws MessagingException;
466:
467: /**
468: * Get the date this message was sent.
469: *
470: * @return the date this message was sent
471: * @throws MessagingException for failures
472: */
473: public abstract Date getSentDate() throws MessagingException;
474:
475: /**
476: * Set the sent date of this message.
477: *
478: * @param date the sent date of this message
479: * @throws IllegalWriteException if the underlying
480: * implementation does not support modification
481: * of existing values
482: * @throws IllegalStateException if this message is
483: * obtained from a READ_ONLY folder.
484: * @throws MessagingException for other failures
485: */
486: public abstract void setSentDate(Date date) throws MessagingException;
487:
488: /**
489: * Get the date this message was received.
490: *
491: * @return the date this message was received
492: * @throws MessagingException for failures
493: */
494: public abstract Date getReceivedDate() throws MessagingException;
495:
496: /**
497: * Returns a <code>Flags</code> object containing the flags for
498: * this message. <p>
499: *
500: * Modifying any of the flags in this returned Flags object will
501: * not affect the flags of this message. Use <code>setFlags()</code>
502: * to do that.
503: *
504: * @return Flags object containing the flags for this message
505: * @throws MessagingException for failures
506: * @see jakarta.mail.Flags
507: * @see #setFlags
508: */
509: public abstract Flags getFlags() throws MessagingException;
510:
511: /**
512: * Check whether the flag specified in the <code>flag</code>
513: * argument is set in this message. <p>
514: *
515: * The default implementation uses <code>getFlags</code>.
516: *
517: * @param flag the flag
518: * @return value of the specified flag for this message
519: * @throws MessagingException for failures
520: * @see jakarta.mail.Flags.Flag#ANSWERED
521: * @see jakarta.mail.Flags.Flag#DELETED
522: * @see jakarta.mail.Flags.Flag#DRAFT
523: * @see jakarta.mail.Flags.Flag#FLAGGED
524: * @see jakarta.mail.Flags.Flag#RECENT
525: * @see jakarta.mail.Flags.Flag#SEEN
526: * @see jakarta.mail.Flags.Flag
527: */
528: public boolean isSet(Flags.Flag flag) throws MessagingException {
529: return getFlags().contains(flag);
530: }
531:
532: /**
533: * Set the specified flags on this message to the specified value.
534: * Note that any flags in this message that are not specified in
535: * the given <code>Flags</code> object are unaffected. <p>
536: *
537: * This will result in a <code>MessageChangedEvent</code> being
538: * delivered to any MessageChangedListener registered on this
539: * Message's containing folder.
540: *
541: * @param flag Flags object containing the flags to be set
542: * @param set the value to be set
543: * @throws IllegalWriteException if the underlying
544: * implementation does not support modification
545: * of existing values.
546: * @throws IllegalStateException if this message is
547: * obtained from a READ_ONLY folder.
548: * @throws MessagingException for other failures
549: * @see jakarta.mail.event.MessageChangedEvent
550: */
551: public abstract void setFlags(Flags flag, boolean set)
552: throws MessagingException;
553:
554: /**
555: * Set the specified flag on this message to the specified value.
556: *
557: * This will result in a <code>MessageChangedEvent</code> being
558: * delivered to any MessageChangedListener registered on this
559: * Message's containing folder. <p>
560: *
561: * The default implementation uses the <code>setFlags</code> method.
562: *
563: * @param flag Flags.Flag object containing the flag to be set
564: * @param set the value to be set
565: * @throws IllegalWriteException if the underlying
566: * implementation does not support modification
567: * of existing values.
568: * @throws IllegalStateException if this message is
569: * obtained from a READ_ONLY folder.
570: * @throws MessagingException for other failures
571: * @see jakarta.mail.event.MessageChangedEvent
572: */
573: public void setFlag(Flags.Flag flag, boolean set)
574: throws MessagingException {
575: Flags f = new Flags(flag);
576: setFlags(f, set);
577: }
578:
579: /**
580: * Get the Message number for this Message.
581: * A Message object's message number is the relative
582: * position of this Message in its Folder. Note that the message
583: * number for a particular Message can change during a session
584: * if other messages in the Folder are deleted and expunged. <p>
585: *
586: * Valid message numbers start at 1. Messages that do not belong
587: * to any folder (like newly composed or derived messages) have 0
588: * as their message number.
589: *
590: * @return the message number
591: */
592: public int getMessageNumber() {
593: return msgnum;
594: }
595:
596: /**
597: * Set the Message number for this Message. This method is
598: * invoked only by the implementation classes.
599: *
600: * @param msgnum the message number
601: */
602: protected void setMessageNumber(int msgnum) {
603: this.msgnum = msgnum;
604: }
605:
606: /**
607: * Get the folder from which this message was obtained. If
608: * this is a new message or nested message, this method returns
609: * null.
610: *
611: * @return the containing folder
612: */
613: public Folder getFolder() {
614: return folder;
615: }
616:
617: /**
618: * Checks whether this message is expunged. All other methods except
619: * <code>getMessageNumber()</code> are invalid on an expunged
620: * Message object. <p>
621: *
622: * Messages that are expunged due to an explict <code>expunge()</code>
623: * request on the containing Folder are removed from the Folder
624: * immediately. Messages that are externally expunged by another source
625: * are marked "expunged" and return true for the isExpunged() method,
626: * but they are not removed from the Folder until an explicit
627: * <code>expunge()</code> is done on the Folder. <p>
628: *
629: * See the description of <code>expunge()</code> for more details on
630: * expunge handling.
631: *
632: * @return true if the message is expunged
633: * @see Folder#expunge
634: */
635: public boolean isExpunged() {
636: return expunged;
637: }
638:
639: /**
640: * Sets the expunged flag for this Message. This method is to
641: * be used only by the implementation classes.
642: *
643: * @param expunged the expunged flag
644: */
645: protected void setExpunged(boolean expunged) {
646: this.expunged = expunged;
647: }
648:
649: /**
650: * Get a new Message suitable for a reply to this message.
651: * The new Message will have its attributes and headers
652: * set up appropriately. Note that this new message object
653: * will be empty, that is, it will <strong>not</strong> have a "content".
654: * These will have to be suitably filled in by the client. <p>
655: *
656: * If <code>replyToAll</code> is set, the new Message will be addressed
657: * to all recipients of this message. Otherwise, the reply will be
658: * addressed to only the sender of this message (using the value
659: * of the <code>getReplyTo</code> method). <p>
660: *
661: * The "Subject" field is filled in with the original subject
662: * prefixed with "Re:" (unless it already starts with "Re:"). <p>
663: *
664: * The reply message will use the same session as this message.
665: *
666: * @param replyToAll reply should be sent to all recipients
667: * of this message
668: * @return the reply Message
669: * @throws MessagingException for failures
670: */
671: public abstract Message reply(boolean replyToAll) throws MessagingException;
672:
673: /**
674: * Save any changes made to this message into the message-store
675: * when the containing folder is closed, if the message is contained
676: * in a folder. (Some implementations may save the changes
677: * immediately.) Update any header fields to be consistent with the
678: * changed message contents. If any part of a message's headers or
679: * contents are changed, saveChanges must be called to ensure that
680: * those changes are permanent. If saveChanges is not called, any
681: * such modifications may or may not be saved, depending on the
682: * message store and folder implementation. <p>
683: *
684: * Messages obtained from folders opened READ_ONLY should not be
685: * modified and saveChanges should not be called on such messages.
686: *
687: * @throws IllegalStateException if this message is
688: * obtained from a READ_ONLY folder.
689: * @throws IllegalWriteException if the underlying
690: * implementation does not support modification
691: * of existing values.
692: * @throws MessagingException for other failures
693: */
694: public abstract void saveChanges() throws MessagingException;
695:
696: /**
697: * Apply the specified Search criterion to this message.
698: *
699: * @param term the Search criterion
700: * @return true if the Message matches this search
701: * criterion, false otherwise.
702: * @throws MessagingException for failures
703: * @see jakarta.mail.search.SearchTerm
704: */
705: public boolean match(SearchTerm term) throws MessagingException {
706: return term.match(this);
707: }
708: }