Skip to content

Package: MultipartReport

MultipartReport

nameinstructionbranchcomplexitylinemethod
MultipartReport()
M: 23 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
MultipartReport(DataSource)
M: 9 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
MultipartReport(String, Report)
M: 55 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 14 C: 0
0%
M: 1 C: 0
0%
MultipartReport(String, Report, InternetHeaders)
M: 22 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
MultipartReport(String, Report, MimeMessage)
M: 19 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
addBodyPart(BodyPart)
M: 13 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
addBodyPart(BodyPart, int)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeliveryStatus()
M: 27 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
getReport()
M: 28 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
getReturnedMessage()
M: 31 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
getText()
M: 50 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
getTextBodyPart()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
removeBodyPart(BodyPart)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
removeBodyPart(int)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setBodyPart(BodyPart, int)
M: 21 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
setDeliveryStatus(DeliveryStatus)
M: 27 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
setReport(Report)
M: 38 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
setReturnedMessage(MimeMessage)
M: 27 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
setSubType(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setText(String)
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
setTextBodyPart(MimeBodyPart)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 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 org.eclipse.angus.mail.dsn;
18:
19: import java.io.*;
20: import java.util.Vector;
21:
22: import jakarta.activation.*;
23: import jakarta.mail.*;
24: import jakarta.mail.internet.*;
25:
26: /**
27: * A multipart/report message content, as defined in
28: * <A HREF="http://www.ietf.org/rfc/rfc3462.txt" TARGET="_top">RFC 3462</A>.
29: * A multipart/report content is a container for mail reports
30: * of any kind, and is most often used to return a delivery
31: * status report or a disposition notification report. <p>
32: *
33: * A MultipartReport object is a special type of MimeMultipart
34: * object with a restricted set of body parts. A MultipartReport
35: * object contains:
36: * <ul>
37: * <li>[Required] A human readable text message describing the
38: * reason the report was generated.</li>
39: * <li>[Required] A {@link Report} object containing the
40: * details for why the report was generated.</li>
41: * <li>[Optional] A returned copy of the entire message, or just
42: * its headers, which caused the generation of this report.
43: * </ul>
44: * Many of the normal MimeMultipart operations are restricted to
45: * ensure that the MultipartReport object always follows this
46: * structure.
47: *
48: * @since        JavaMail 1.4
49: */
50: public class MultipartReport extends MimeMultipart {
51: protected boolean constructed; // true when done with constructor
52:
53: /**
54: * Construct a multipart/report object with no content.
55: *
56: * @exception        MessagingException for failures
57: */
58: public MultipartReport() throws MessagingException {
59:         super("report");
60:         // always at least two body parts
61:         MimeBodyPart mbp = new MimeBodyPart();
62:         setBodyPart(mbp, 0);
63:         mbp = new MimeBodyPart();
64:         setBodyPart(mbp, 1);
65:         constructed = true;
66: }
67:
68: /**
69: * Construct a multipart/report object with the specified plain
70: * text and report type (DeliveryStatus or DispositionNotification)
71: * to be returned to the user.
72: *
73: * @param        text        the plain text
74: * @param        report        the Report object
75: * @exception        MessagingException for failures
76: */
77: public MultipartReport(String text, Report report)
78:                                 throws MessagingException {
79:         super("report");
80:         ContentType ct = new ContentType(contentType);
81:         String reportType = report.getType();
82:         ct.setParameter("report-type", reportType);
83:         contentType = ct.toString();
84:         MimeBodyPart mbp = new MimeBodyPart();
85:         mbp.setText(text);
86:         setBodyPart(mbp, 0);
87:         mbp = new MimeBodyPart();
88:         ct = new ContentType("message", reportType, null);
89:         mbp.setContent(report, ct.toString());
90:         setBodyPart(mbp, 1);
91:         constructed = true;
92: }
93:
94: /**
95: * Construct a multipart/report object with the specified plain
96: * text, report, and original message to be returned to the user.
97: *
98: * @param        text        the plain text
99: * @param        report        the Report object
100: * @param        msg        the message this report is about
101: * @exception        MessagingException for failures
102: */
103: public MultipartReport(String text, Report report, MimeMessage msg)
104:                                 throws MessagingException {
105:         this(text, report);
106:•        if (msg != null) {
107:          MimeBodyPart mbp = new MimeBodyPart();
108:          mbp.setContent(msg, "message/rfc822");
109:          setBodyPart(mbp, 2);
110:         }
111: }
112:
113: /**
114: * Construct a multipart/report object with the specified plain
115: * text, report, and headers from the original message
116: * to be returned to the user.
117: *
118: * @param        text        the plain text
119: * @param        report        the Report object
120: * @param        hdr        the headers of the message this report is about
121: * @exception        MessagingException for failures
122: */
123: public MultipartReport(String text, Report report, InternetHeaders hdr)
124:                                 throws MessagingException {
125:         this(text, report);
126:•        if (hdr != null) {
127:          MimeBodyPart mbp = new MimeBodyPart();
128:          mbp.setContent(new MessageHeaders(hdr), "text/rfc822-headers");
129:          setBodyPart(mbp, 2);
130:         }
131: }
132:
133: /**
134: * Constructs a MultipartReport object and its bodyparts from the
135: * given DataSource.
136: *
137: * @param        ds        DataSource, can be a MultipartDataSource
138: * @exception        MessagingException for failures
139: */
140: public MultipartReport(DataSource ds) throws MessagingException {
141:         super(ds);
142:         parse();
143:         constructed = true;
144:         /*
145:          * Can't fail to construct object because some programs just
146:          * want to treat this as a Multipart and examine the parts.
147:          *
148:         if (getCount() < 2 || getCount() > 3)        // XXX allow extra parts
149:          throw new MessagingException(
150:                 "Wrong number of parts in multipart/report: " + getCount());
151:          */
152: }
153:
154: /**
155: * Get the plain text to be presented to the user, if there is any.
156: * Rarely, the message may contain only HTML text, or no text at
157: * all. If the text body part of this multipart/report object is
158: * of type text/plain, or if it is of type multipart/alternative
159: * and contains a text/plain part, the text from that part is
160: * returned. Otherwise, null is return and the {@link #getTextBodyPart
161: * getTextBodyPart} method may be used to extract the data.
162: *
163: * @return        the text
164: * @exception        MessagingException for failures
165: */
166: public synchronized String getText() throws MessagingException {
167:         try {
168:          BodyPart bp = getBodyPart(0);
169:•         if (bp.isMimeType("text/plain"))
170:                 return (String)bp.getContent();
171:•         if (bp.isMimeType("multipart/alternative")) {
172:                 Multipart mp = (Multipart)bp.getContent();
173:•                for (int i = 0; i < mp.getCount(); i++) {
174:                  bp = mp.getBodyPart(i);
175:•                 if (bp.isMimeType("text/plain"))
176:                         return (String)bp.getContent();
177:                 }
178:          }
179:         } catch (IOException ex) {
180:          throw new MessagingException("Exception getting text content", ex);
181:         }
182:         return null;
183: }
184:
185: /**
186: * Set the message to be presented to the user as just a text/plain
187: * part containing the specified text.
188: *
189: * @param        text        the text
190: * @exception        MessagingException for failures
191: */
192: public synchronized void setText(String text) throws MessagingException {
193:         MimeBodyPart mbp = new MimeBodyPart();
194:         mbp.setText(text);
195:         setBodyPart(mbp, 0);
196: }
197:
198: /**
199: * Return the body part containing the message to be presented to
200: * the user, usually just a text/plain part.
201: *
202: * @return        the body part containing the text
203: * @exception        MessagingException for failures
204: */
205: public synchronized MimeBodyPart getTextBodyPart()
206:                                 throws MessagingException {
207:         return (MimeBodyPart)getBodyPart(0);
208: }
209:
210: /**
211: * Set the body part containing the text to be presented to the
212: * user. Usually this a text/plain part, but it might also be
213: * a text/html part or a multipart/alternative part containing
214: * text/plain and text/html parts. Any type is allowed here
215: * but these types are most common.
216: *
217: * @param        mbp        the body part containing the text
218: * @exception        MessagingException for failures
219: */
220: public synchronized void setTextBodyPart(MimeBodyPart mbp)
221:                                 throws MessagingException {
222:         setBodyPart(mbp, 0);
223: }
224:
225: /**
226: * Get the report associated with this multipart/report.
227: *
228: * @return        the Report object
229: * @exception        MessagingException for failures
230: * @since        JavaMail 1.4.2
231: */
232: public synchronized Report getReport() throws MessagingException {
233:•        if (getCount() < 2)
234:          return null;
235:         BodyPart bp = getBodyPart(1);
236:         try {
237:          Object content = bp.getContent();
238:•         if (!(content instanceof Report))
239:                 return null;
240:          return (Report)content;
241:         } catch (IOException ex) {
242:          throw new MessagingException("IOException getting Report", ex);
243:         }
244: }
245:
246: /**
247: * Set the report associated with this multipart/report.
248: *
249: * @param        report        the Report object
250: * @exception        MessagingException for failures
251: * @since        JavaMail 1.4.2
252: */
253: public synchronized void setReport(Report report)
254:                                 throws MessagingException {
255:         MimeBodyPart mbp = new MimeBodyPart();
256:         ContentType ct = new ContentType(contentType);
257:         String reportType = report.getType();
258:         ct.setParameter("report-type", reportType);
259:         contentType = ct.toString();
260:         ct = new ContentType("message", reportType, null);
261:         mbp.setContent(report, ct.toString());
262:         setBodyPart(mbp, 1);
263: }
264:
265: /**
266: * Get the delivery status associated with this multipart/report.
267: *
268: * @return        the delivery status
269: * @exception        MessagingException for failures
270: * @deprecated        use getReport instead
271: */
272: @Deprecated
273: public synchronized DeliveryStatus getDeliveryStatus()
274:                                 throws MessagingException {
275:•        if (getCount() < 2)
276:          return null;
277:         BodyPart bp = getBodyPart(1);
278:•        if (!bp.isMimeType("message/delivery-status"))
279:          return null;
280:         try {
281:          return (DeliveryStatus)bp.getContent();
282:         } catch (IOException ex) {
283:          throw new MessagingException("IOException getting DeliveryStatus",
284:                                         ex);
285:         }
286: }
287:
288: /**
289: * Set the delivery status associated with this multipart/report.
290: *
291: * @param        status the deliver status
292: * @exception        MessagingException for failures
293: * @deprecated        use setReport instead
294: */
295: public synchronized void setDeliveryStatus(DeliveryStatus status)
296:                                 throws MessagingException {
297:         MimeBodyPart mbp = new MimeBodyPart();
298:         mbp.setContent(status, "message/delivery-status");
299:         setBodyPart(mbp, 1);
300:         ContentType ct = new ContentType(contentType);
301:         ct.setParameter("report-type", "delivery-status");
302:         contentType = ct.toString();
303: }
304:
305: /**
306: * Get the original message that is being returned along with this
307: * multipart/report. If no original message is included, null is
308: * returned. In some cases only the headers of the original
309: * message will be returned as an object of type MessageHeaders.
310: *
311: * @return        the returned message
312: * @exception        MessagingException for failures
313: */
314: public synchronized MimeMessage getReturnedMessage()
315:                                 throws MessagingException {
316:•        if (getCount() < 3)
317:          return null;
318:         BodyPart bp = getBodyPart(2);
319:•        if (!bp.isMimeType("message/rfc822") &&
320:•                !bp.isMimeType("text/rfc822-headers"))
321:          return null;
322:         try {
323:          return (MimeMessage)bp.getContent();
324:         } catch (IOException ex) {
325:          throw new MessagingException("IOException getting ReturnedMessage",
326:                                         ex);
327:         }
328: }
329:
330: /**
331: * Set the original message to be returned as part of the
332: * multipart/report. If msg is null, any previously set
333: * returned message or headers is removed.
334: *
335: * @param        msg        the returned message
336: * @exception        MessagingException for failures
337: */
338: public synchronized void setReturnedMessage(MimeMessage msg)
339:                                 throws MessagingException {
340:•        if (msg == null) {
341:          super.removeBodyPart(2);
342:          return;
343:         }
344:         MimeBodyPart mbp = new MimeBodyPart();
345:•        if (msg instanceof MessageHeaders)
346:          mbp.setContent(msg, "text/rfc822-headers");
347:         else
348:          mbp.setContent(msg, "message/rfc822");
349:         setBodyPart(mbp, 2);
350: }
351:
352: private synchronized void setBodyPart(BodyPart part, int index)
353:                                 throws MessagingException {
354:•        if (parts == null)        // XXX - can never happen?
355:          parts = new Vector<BodyPart>();
356:
357:•        if (index < parts.size())
358:          super.removeBodyPart(index);
359:         super.addBodyPart(part, index);
360: }
361:
362:
363: // Override Multipart methods to preserve integrity of multipart/report.
364:
365: /**
366: * Set the subtype. Throws MessagingException.
367: *
368: * @param        subtype                Subtype
369: * @exception        MessagingException        always; can't change subtype
370: */
371: public synchronized void setSubType(String subtype)
372:                         throws MessagingException {
373:         throw new MessagingException("Can't change subtype of MultipartReport");
374: }
375:
376: /**
377: * Remove the specified part from the multipart message.
378: * Not allowed on a multipart/report object.
379: *
380: * @param part        The part to remove
381: * @exception        MessagingException always
382: */
383: public boolean removeBodyPart(BodyPart part) throws MessagingException {
384:         throw new MessagingException(
385:          "Can't remove body parts from multipart/report");
386: }
387:
388: /**
389: * Remove the part at specified location (starting from 0).
390: * Not allowed on a multipart/report object.
391: *
392: * @param index        Index of the part to remove
393: * @exception        MessagingException        always
394: */
395: public void removeBodyPart(int index) throws MessagingException {
396:         throw new MessagingException(
397:          "Can't remove body parts from multipart/report");
398: }
399:
400: /**
401: * Adds a Part to the multipart.
402: * Not allowed on a multipart/report object.
403: *
404: * @param part The Part to be appended
405: * @exception MessagingException        always
406: */
407: public synchronized void addBodyPart(BodyPart part)
408:                 throws MessagingException {
409:         // Once constructor is done, don't allow this anymore.
410:•        if (!constructed)
411:          super.addBodyPart(part);
412:         else
413:          throw new MessagingException(
414:                 "Can't add body parts to multipart/report 1");
415: }
416:
417: /**
418: * Adds a BodyPart at position <code>index</code>.
419: * Not allowed on a multipart/report object.
420: *
421: * @param part The BodyPart to be inserted
422: * @param index Location where to insert the part
423: * @exception MessagingException        always
424: */
425: public synchronized void addBodyPart(BodyPart part, int index)
426:                                 throws MessagingException {
427:         throw new MessagingException(
428:          "Can't add body parts to multipart/report 2");
429: }
430: }