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