Open Source Repository

/** DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.** Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.** The contents of this file are subject to the terms of either the GNU* General Public License Version 2 only ("GPL") or the Common Development* and Distribution License("CDDL") (collectively, the "License"). You* may not use this file except in compliance with the License. You can obtain* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific* language governing permissions and limitations under the License.** When distributing the software, include this License Header Notice in each* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.* Sun designates this particular file as subject to the "Classpath" exception* as provided by Sun in the GPL Version 2 section of the License file that* accompanied this code. If applicable, add the following below the License* Header, with the fields enclosed by brackets [] replaced by your own* identifying information: "Portions Copyrighted [year]* [name of copyright owner]"** Contributor(s):** If you wish your version of this file to be governed by only the CDDL or* only the GPL Version 2, indicate your decision by adding "[Contributor]* elects to include this software in this distribution under the [CDDL or GPL* Version 2] license." If you don't indicate a single choice of license, a* recipient has the option to distribute your version of this file under* either the CDDL, the GPL Version 2 or to extend the choice of license to* its licensees as provided above. However, if you add GPL Version 2 code* and therefore, elected the GPL Version 2 license, then the option applies* only if the new code is made subject to such option by the copyright* holder.*//** @(#)MultipartReport.java 1.7 07/05/04*/package com.sun.mail.dsn;import java.io.*;import java.util.Vector;import javax.activation.*;import javax.mail.*;import javax.mail.internet.*;/*** A multipart/report message content, as defined in* <A HREF="http://www.ietf.org/rfc/rfc3462.txt">RFC 3462</A>.* A multipart/report content is a container for mail reports* of any kind, and is most often used to return a delivery* status report. This class only supports that most common* usage. <p>** A MultipartReport object is a special type of MimeMultipart* object with a restricted set of body parts. A MultipartReport* object contains:* <ul>* <li>[Required] A human readable text message describing the* reason the report was generated.</li>* <li>[Required] A {@link DeliveryStatus} object containing the* details for why the report was generated.</li>* <li>[Optional] A returned copy of the entire message, or just* its headers, which caused the generation of this report.* </ul>* Many of the normal MimeMultipart operations are restricted to* ensure that the MultipartReport object always follows this* structure.*/public class MultipartReport extends MimeMultipart {protected boolean constructed; // true when done with constructor/*** Construct a multipart/report object with no content.*/public MultipartReport() throws MessagingException {super("report");// always at least two body partsMimeBodyPart mbp = new MimeBodyPart();setBodyPart(mbp, 0);mbp = new MimeBodyPart();setBodyPart(mbp, 1);constructed = true;}/*** Construct a multipart/report object with the specified plain* text and delivery status to be returned to the user.*/public MultipartReport(String text, DeliveryStatus status)throws MessagingException {super("report");ContentType ct = new ContentType(contentType);ct.setParameter("report-type", "delivery-status");contentType = ct.toString();MimeBodyPart mbp = new MimeBodyPart();mbp.setText(text);setBodyPart(mbp, 0);mbp = new MimeBodyPart();mbp.setContent(status, "message/delivery-status");setBodyPart(mbp, 1);constructed = true;}/*** Construct a multipart/report object with the specified plain* text, delivery status, and original message to be returned to the user.*/public MultipartReport(String text, DeliveryStatus status,MimeMessage msg) throws MessagingException {this(text, status);if (msg != null) {MimeBodyPart mbp = new MimeBodyPart();mbp.setContent(msg, "message/rfc822");setBodyPart(mbp, 2);}}/*** Construct a multipart/report object with the specified plain* text, delivery status, and headers from the original message* to be returned to the user.*/public MultipartReport(String text, DeliveryStatus status,InternetHeaders hdr) throws MessagingException {this(text, status);if (hdr != null) {MimeBodyPart mbp = new MimeBodyPart();mbp.setContent(new MessageHeaders(hdr), "text/rfc822-headers");setBodyPart(mbp, 2);}}/*** Constructs a MultipartReport object and its bodyparts from the * given DataSource. <p>** @param ds DataSource, can be a MultipartDataSource*/public MultipartReport(DataSource ds) throws MessagingException {super(ds);parse();constructed = true;/** Can't fail to construct object because some programs just* want to treat this as a Multipart and examine the parts.*if (getCount() < 2 || getCount() > 3) // XXX allow extra partsthrow new MessagingException("Wrong number of parts in multipart/report: " + getCount());*/}/*** Get the plain text to be presented to the user, if there is any.* Rarely, the message may contain only HTML text, or no text at* all. If the text body part of this multipart/report object is* of type text/plain, or if it is of type multipart/alternative* and contains a text/plain part, the text from that part is* returned. Otherwise, null is return and the {@link #getTextBodyPart* getTextBodyPart} method may be used to extract the data.*/public synchronized String getText() throws MessagingException {try {BodyPart bp = getBodyPart(0);if (bp.isMimeType("text/plain"))return (String)bp.getContent();if (bp.isMimeType("multipart/alternative")) {Multipart mp = (Multipart)bp.getContent();for (int i = 0; i < mp.getCount(); i++) {bp = mp.getBodyPart(i);if (bp.isMimeType("text/plain"))return (String)bp.getContent();}}} catch (IOException ex) {throw new MessagingException("Exception getting text content", ex);}return null;}/*** Set the message to be presented to the user as just a text/plain* part containing the specified text.*/public synchronized void setText(String text) throws MessagingException {MimeBodyPart mbp = new MimeBodyPart();mbp.setText(text);setBodyPart(mbp, 0);}/*** Return the body part containing the message to be presented to* the user, usually just a text/plain part.*/public synchronized MimeBodyPart getTextBodyPart()throws MessagingException {return (MimeBodyPart)getBodyPart(0);}/*** Set the body part containing the text to be presented to the* user. Usually this a text/plain part, but it might also be* a text/html part or a multipart/alternative part containing* text/plain and text/html parts. Any type is allowed here* but these types are most common.*/public synchronized void setTextBodyPart(MimeBodyPart mbp)throws MessagingException {setBodyPart(mbp, 0);}/*** Get the delivery status associated with this multipart/report.*/public synchronized DeliveryStatus getDeliveryStatus()throws MessagingException {if (getCount() < 2)return null;BodyPart bp = getBodyPart(1);if (!bp.isMimeType("message/delivery-status"))return null;try {return (DeliveryStatus)bp.getContent();} catch (IOException ex) {throw new MessagingException("IOException getting DeliveryStatus",ex);}}/*** Set the delivery status associated with this multipart/report.*/public synchronized void setDeliveryStatus(DeliveryStatus status)throws MessagingException {MimeBodyPart mbp = new MimeBodyPart();mbp.setContent(status, "message/delivery-status");setBodyPart(mbp, 2);ContentType ct = new ContentType(contentType);ct.setParameter("report-type", "delivery-status");contentType = ct.toString();}/*** Get the original message that is being returned along with this* multipart/report. If no original message is included, null is* returned. In some cases only the headers of the original* message will be returned as an object of type MessageHeaders.*/public synchronized MimeMessage getReturnedMessage()throws MessagingException {if (getCount() < 3)return null;BodyPart bp = getBodyPart(2);if (!bp.isMimeType("message/rfc822") &&!bp.isMimeType("text/rfc822-headers"))return null;try {return (MimeMessage)bp.getContent();} catch (IOException ex) {throw new MessagingException("IOException getting ReturnedMessage",ex);}}/*** Set the original message to be returned as part of the* multipart/report. If msg is null, any previously set* returned message or headers is removed.*/public synchronized void setReturnedMessage(MimeMessage msg)throws MessagingException {if (msg == null) {BodyPart part = (BodyPart)parts.elementAt(2);super.removeBodyPart(2);return;}MimeBodyPart mbp = new MimeBodyPart();if (msg instanceof MessageHeaders)mbp.setContent(msg, "text/rfc822-headers");elsembp.setContent(msg, "message/rfc822");setBodyPart(mbp, 2);}private synchronized void setBodyPart(BodyPart part, int index) throws MessagingException {if (parts == null) // XXX - can never happen?parts = new Vector();if (index < parts.size())super.removeBodyPart(index);super.addBodyPart(part, index);}// Override Multipart methods to preserve integrity of multipart/report./*** Set the subtype. Throws MessagingException.** @param subtype Subtype* @exception MessagingException always; can't change subtype*/public synchronized void setSubType(String subtype) throws MessagingException {throw new MessagingException("Can't change subtype of MultipartReport");}/*** Remove the specified part from the multipart message.* Not allowed on a multipart/report object.** @param part The part to remove* @exception MessagingException always*/public boolean removeBodyPart(BodyPart part) throws MessagingException {throw new MessagingException("Can't remove body parts from multipart/report");}/*** Remove the part at specified location (starting from 0).* Not allowed on a multipart/report object.** @param index Index of the part to remove* @exception MessagingException always*/public void removeBodyPart(int index) throws MessagingException {throw new MessagingException("Can't remove body parts from multipart/report");}/*** Adds a Part to the multipart.* Not allowed on a multipart/report object.** @param part The Part to be appended* @exception MessagingException always*/public synchronized void addBodyPart(BodyPart part) throws MessagingException {// Once constructor is done, don't allow this anymore.if (!constructed)super.addBodyPart(part);elsethrow new MessagingException("Can't add body parts to multipart/report 1");}/*** Adds a BodyPart at position <code>index</code>.* Not allowed on a multipart/report object.** @param part The BodyPart to be inserted* @param index Location where to insert the part* @exception MessagingException always*/public synchronized void addBodyPart(BodyPart part, int index) throws MessagingException {throw new MessagingException("Can't add body parts to multipart/report 2");}}