913 lines
30 KiB
Java
913 lines
30 KiB
Java
/*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Netscape Messaging Access SDK Version 3.5 code,
|
|
* released on or about June 15, 1998. *
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s): ______________________________________.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 1997 and 1998 Netscape Communications Corporation
|
|
* (http://home.netscape.com/misc/trademarks.html)
|
|
*/
|
|
|
|
package netscape.messaging.mime;
|
|
import java.io.*;
|
|
import java.lang.*;
|
|
import java.util.*;
|
|
import netscape.messaging.mime.MIMEParser;
|
|
|
|
/**
|
|
* The MIMEMultiPart class implements the MIME multi-part Content Type.
|
|
* <p>The multi-part content type represents messages with multiple
|
|
* attachments of potentially different media. This content type
|
|
* describes a message that is made up of one or more sub-body parts.
|
|
* The Multipart type has several subtypes that describe how the
|
|
* sub-parts relate to each other. These include mixed, alternative,
|
|
* digest, and parallel.
|
|
* @author Prasad Yendluri
|
|
*/
|
|
public class MIMEMultiPart extends MIMEBodyPart implements Cloneable
|
|
{
|
|
|
|
//===========================================================================
|
|
//
|
|
// Internal members not visible at the API
|
|
//
|
|
//===========================================================================
|
|
|
|
private static final int UNINITIALIZED = -1;
|
|
private static final String[] m_stringDisposition = { "Attachment", "Inline"};
|
|
private static final String[] m_stringEncoding = { "base64", "quoted-printable",
|
|
"binary", "7bit", "8bit" };
|
|
private static final String MULTIPART = "MultiPart";
|
|
|
|
//private int m_contentType;
|
|
//private int m_contentTransferEncoding;
|
|
protected int m_parsedPart;
|
|
private int m_bpCount; // count of bodyparts
|
|
private boolean m_needPreamble;
|
|
protected boolean m_endPart;
|
|
|
|
// Vector to hold the bodyparts.
|
|
private Vector m_bodyParts;
|
|
private String m_boundary;
|
|
private String m_preamble;
|
|
private int m_contentTransferEncoding;
|
|
|
|
|
|
//===========================================================================
|
|
//
|
|
// CONSTRUCTORS
|
|
//
|
|
//===========================================================================
|
|
|
|
/**
|
|
* Constructs a MIMEMultiPart object.
|
|
* Default constructor for the MIMEMultiPart
|
|
*/
|
|
public MIMEMultiPart ()
|
|
{
|
|
m_parsedPart = 0;
|
|
m_contentDisposition = UNINITIALIZED;
|
|
m_contentTransferEncoding = UNINITIALIZED;
|
|
m_needPreamble = false;
|
|
m_bodyParts = new Vector();
|
|
m_boundary = null;
|
|
m_UserObject = null;
|
|
}
|
|
|
|
|
|
/**
|
|
* Constructs a MIMEMultiPart object with the specified text and filename.
|
|
* Both textIS and filename cannot be null or an exception is thrown.
|
|
* (See MIMEMessage() if you need to do this.)
|
|
* @param textIS InputStream to text that becomes (first) text part of the multi-part.
|
|
* @param filename Name of the file that becomes second part of the multi-part.
|
|
* @param encoding Encoding for the file attachment. To select a default encoding, use -1.
|
|
* @see #MIMEMessage
|
|
* @see MIMEBodyPart#BASE64
|
|
* @see MIMEBodyPart#QP
|
|
* @see MIMEBodyPart#BINARY
|
|
* @see MIMEBodyPart#E7BIT
|
|
* @see MIMEBodyPart#E8BIT
|
|
* @exception MIMEException If filename is null or textIS null.
|
|
* @exception FileNotFoundException If filename file does not exist
|
|
* @exception SecurityException If filename file can not be accessed
|
|
* @exception IOExcepton On IO Errors on filename or textIS.
|
|
*/
|
|
public MIMEMultiPart (InputStream textIS, String filename, int encoding) throws
|
|
MIMEException, FileNotFoundException, SecurityException, IOException
|
|
{
|
|
MIMEBasicPart l_txtPart;
|
|
MIMEBasicPart l_filePart;
|
|
FileInputStream l_fis;
|
|
fileMIMEType l_fmt;
|
|
|
|
m_parsedPart = 0;
|
|
m_contentDisposition = UNINITIALIZED;
|
|
m_contentTransferEncoding = UNINITIALIZED;
|
|
m_needPreamble = false;
|
|
m_bodyParts = new Vector();
|
|
m_boundary = null;
|
|
|
|
if (textIS == null)
|
|
throw new MIMEException ("Invalid null InputStream");
|
|
|
|
if (filename == null)
|
|
throw new MIMEException ("Invalid null filename:" + filename);
|
|
|
|
if ((encoding != -1) && (encoding < MIMEBodyPart.BASE64 || encoding > MIMEBodyPart.E8BIT))
|
|
|
|
throw new MIMEException ("Invalid MIME encoding:" + encoding);
|
|
this.setContentSubType ("mixed");
|
|
|
|
l_fis = new FileInputStream (filename);
|
|
|
|
// The text-part!
|
|
l_txtPart = new MIMEBasicPart (MIMEBasicPart.TEXT);
|
|
|
|
l_txtPart.setContentSubType ("plain");
|
|
l_txtPart.setContentTypeParams ("charset=us-ascii");
|
|
l_txtPart.setContentEncoding(MIMEBodyPart.E7BIT);
|
|
//l_txtPart.setContentDisposition(MIMEBodyPart.INLINE);
|
|
|
|
l_txtPart.setBodyData (textIS);
|
|
|
|
// The file-part
|
|
l_fmt = MIMEHelper.getFileMIMEType (filename);
|
|
|
|
if (l_fmt == null)
|
|
throw new MIMEException ("Can't determine MIME info for file: " + filename);
|
|
|
|
l_filePart = new MIMEBasicPart (l_fmt.content_type);
|
|
|
|
l_filePart.setContentSubType (l_fmt.content_subtype);
|
|
|
|
if (l_fmt.content_params != null)
|
|
l_filePart.setContentTypeParams (l_fmt.content_params);
|
|
else
|
|
l_filePart.setContentTypeParams (new String ("name=" + l_fmt.file_shortname));
|
|
|
|
if (encoding == -1)
|
|
l_filePart.setContentEncoding(l_fmt.mime_encoding);
|
|
else
|
|
l_filePart.setContentEncoding (encoding);
|
|
|
|
if (l_fmt.content_type == MIMEBasicPart.TEXT);
|
|
//l_filePart.setContentDisposition (MIMEBodyPart.INLINE);
|
|
else
|
|
{
|
|
//l_filePart.setContentDisposition (MIMEBodyPart.ATTACHMENT);
|
|
l_filePart.setContentDispParams (new String ("filename=" + l_fmt.file_shortname));
|
|
l_filePart.setContentDescription (l_fmt.file_shortname);
|
|
}
|
|
|
|
// set body-data of this part
|
|
l_filePart.setBodyData (l_fis);
|
|
|
|
// Add this part to multi-part
|
|
this.addBodyPart (l_txtPart, false);
|
|
this.addBodyPart (l_filePart, false);
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
//
|
|
// Methods overridden from MIMEBodyPart
|
|
//
|
|
//===========================================================================
|
|
|
|
/**
|
|
* Returns Content-Type of this MIME Part. Always returns the String "MultiPart".
|
|
*/
|
|
public String getContentType ()
|
|
{
|
|
return (MULTIPART);
|
|
}
|
|
|
|
|
|
//===========================================================================
|
|
//
|
|
// Methods Specific to this Class alone.
|
|
//
|
|
//===========================================================================
|
|
|
|
/**
|
|
* Returns the count of BodyParts in this MultiPart or
|
|
* Zero (0) if no parts exist.
|
|
*/
|
|
public int getBodyPartCount ()
|
|
{
|
|
if (m_bodyParts != null)
|
|
return (m_bodyParts.size());
|
|
else
|
|
return (0);
|
|
}
|
|
|
|
/**
|
|
* Returns an Object of corresponding MIME BodyPart type at the
|
|
* specified index of this MultiPart.
|
|
* @param index Index for the BodyPart to return. Index ranges from 0 to (count_of_parts -1).
|
|
* @param clone Whether to return a reference to the internal BodyPart object or a cloned copy;
|
|
* if true: cloned copy; if false: reference to the BodyPart object.
|
|
* @exception MIMEException If invalid index.
|
|
* @see MIMEBasicPart
|
|
* @see MIMEMessagePart
|
|
* @see MIMEMultiPart
|
|
* @see MIMEMultiPart#getBodyPartCount
|
|
*/
|
|
public Object getBodyPart (int index, boolean clone) throws MIMEException
|
|
{
|
|
if (index >= m_bodyParts.size() || index < 0)
|
|
throw new MIMEException ("getBodyPart(). Index out of range: " + index);
|
|
|
|
Object obj = m_bodyParts.elementAt (index);
|
|
|
|
if (obj instanceof MIMEBasicPart)
|
|
{
|
|
MIMEBasicPart part = (MIMEBasicPart) obj;
|
|
|
|
try
|
|
{
|
|
if (clone)
|
|
return (part.clone());
|
|
else
|
|
return (part);
|
|
}
|
|
catch (CloneNotSupportedException e)
|
|
{
|
|
throw new MIMEException (e.getMessage());
|
|
}
|
|
}
|
|
else if (obj instanceof MIMEMessagePart)
|
|
{
|
|
MIMEMessagePart part = (MIMEMessagePart) obj;
|
|
|
|
try
|
|
{
|
|
if (clone)
|
|
return (part.clone());
|
|
else
|
|
return (part);
|
|
}
|
|
catch (CloneNotSupportedException e)
|
|
{
|
|
throw new MIMEException (e.getMessage());
|
|
}
|
|
}
|
|
else if (obj instanceof MIMEMultiPart)
|
|
{
|
|
MIMEMultiPart part = (MIMEMultiPart) obj;
|
|
|
|
try
|
|
{
|
|
if (clone)
|
|
return (part.clone());
|
|
else
|
|
return (part);
|
|
}
|
|
catch (CloneNotSupportedException e)
|
|
{
|
|
throw new MIMEException (e.getMessage());
|
|
}
|
|
}
|
|
else
|
|
throw new MIMEException ("Invalid bodyPart!");
|
|
}
|
|
|
|
/**
|
|
* The following is an internal routine. Not to be exposed at the API.
|
|
* @exception MIMEException If the multipart is malformed.
|
|
* @exception IOException If IO error occurs.
|
|
*/
|
|
protected void putByteStream (OutputStream os, boolean needPreamble)
|
|
throws IOException, MIMEException
|
|
{
|
|
if (needPreamble == true)
|
|
m_needPreamble = true;
|
|
else
|
|
m_needPreamble = false; // In case we did not reset last pass due exception
|
|
|
|
putByteStream (os);
|
|
|
|
m_needPreamble = false; // reset after done.
|
|
}
|
|
|
|
/**
|
|
* Outputs a byte stream for this Message in MIME format.
|
|
* Applies transfer encoding all bodyParts as applicable.
|
|
* @param os OutputStream to be written to.
|
|
* @exception IOException If an IO error occurs.
|
|
* @exception MIMEException If detects an error during encoding.
|
|
*/
|
|
public void putByteStream (OutputStream os) throws IOException, MIMEException
|
|
{
|
|
int l_bpCount = m_bodyParts.size();
|
|
|
|
if ((m_bodyParts == null) || (l_bpCount < 1))
|
|
throw new MIMEException ("MIMEMultiPart.putByteStream(). No bodyParts!");
|
|
|
|
// Headers first
|
|
StringBuffer l_hdrbuf = new StringBuffer (HDRBUFSZ);
|
|
byte[] l_bytebuf;
|
|
String l_boundary;
|
|
boolean l_fQBounds=false;
|
|
|
|
if (m_boundary != null && m_boundary.length() > 0)
|
|
{
|
|
l_boundary = m_boundary;
|
|
l_fQBounds = true;
|
|
}
|
|
else
|
|
l_boundary = generateBoundary();
|
|
|
|
// content-type
|
|
l_hdrbuf.append ("Content-Type: multipart/");
|
|
|
|
if (m_contentSubType != null)
|
|
l_hdrbuf.append (m_contentSubType);
|
|
else
|
|
throw new MIMEException ("putByteStream: No content-subtype." );
|
|
|
|
if (m_contentTypeParams != null && !m_contentTypeParams.startsWith ("boundary"))
|
|
{
|
|
l_hdrbuf.append ("; ");
|
|
l_hdrbuf.append (m_contentTypeParams);
|
|
l_hdrbuf.append ("; boundary=");
|
|
if (l_fQBounds)
|
|
l_hdrbuf.append ('"');
|
|
l_hdrbuf.append (l_boundary);
|
|
if (l_fQBounds)
|
|
l_hdrbuf.append ('"');
|
|
l_hdrbuf.append ("\r\n");
|
|
}
|
|
else
|
|
{
|
|
l_hdrbuf.append ("; boundary=");
|
|
if (l_fQBounds)
|
|
l_hdrbuf.append ('"');
|
|
l_hdrbuf.append (l_boundary);
|
|
if (l_fQBounds)
|
|
l_hdrbuf.append ('"');
|
|
l_hdrbuf.append ("\r\n");
|
|
}
|
|
|
|
|
|
// write the header to os
|
|
try
|
|
{
|
|
//l_bytebuf = l_hdrbuf.toString().getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_hdrbuf.toString());
|
|
os.write (l_bytebuf);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new MIMEException ("Content-Type: " + e.getMessage());
|
|
}
|
|
|
|
// contentID
|
|
if (m_contentID != null)
|
|
{
|
|
l_hdrbuf.setLength (0);
|
|
l_hdrbuf.append ("Content-ID: " + m_contentID);
|
|
l_hdrbuf.append ("\r\n");
|
|
|
|
try
|
|
{
|
|
// l_bytebuf = l_hdrbuf.toString().getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_hdrbuf.toString());
|
|
os.write (l_bytebuf);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new MIMEException ("Content-ID: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
// contentDisposition
|
|
if (m_contentDisposition != UNINITIALIZED)
|
|
{
|
|
l_hdrbuf.setLength (0);
|
|
l_hdrbuf.append ("Content-Disposition: " +
|
|
m_stringDisposition [m_contentDisposition]);
|
|
|
|
if (m_contentDispParams != null)
|
|
{
|
|
l_hdrbuf.append ("; ");
|
|
l_hdrbuf.append (m_contentDispParams);
|
|
}
|
|
|
|
l_hdrbuf.append ("\r\n");
|
|
|
|
try
|
|
{
|
|
//l_bytebuf = l_hdrbuf.toString().getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_hdrbuf.toString());
|
|
os.write (l_bytebuf);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new MIMEException ("Content-Disposition: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
// contentDescription
|
|
if (m_contentDescription != null)
|
|
{
|
|
l_hdrbuf.setLength (0);
|
|
l_hdrbuf.append ("Content-Description: " + m_contentDescription);
|
|
l_hdrbuf.append ("\r\n");
|
|
|
|
try
|
|
{
|
|
//l_bytebuf = l_hdrbuf.toString().getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_hdrbuf.toString());
|
|
os.write (l_bytebuf);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new MIMEException ("Content-Description: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
// This is the top-level multi-part. Add content-encoding
|
|
if (m_needPreamble == true && m_contentTransferEncoding != UNINITIALIZED)
|
|
{
|
|
boolean fwriteit = false;
|
|
switch (m_contentTransferEncoding)
|
|
{
|
|
case BINARY:
|
|
case E7BIT:
|
|
case E8BIT:
|
|
l_hdrbuf.setLength (0);
|
|
l_hdrbuf.append ("Content-Transfer-Encoding: " +
|
|
m_stringEncoding [m_contentTransferEncoding]);
|
|
l_hdrbuf.append ("\r\n");
|
|
fwriteit = true;
|
|
break;
|
|
}
|
|
|
|
|
|
if (fwriteit) try
|
|
{
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_hdrbuf.toString());
|
|
os.write (l_bytebuf);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new MIMEException ("Content-Encodding: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
// blank-line after headers
|
|
//l_bytebuf = new String("\r\n").getBytes("iso-8859-1");
|
|
os.write (CRLF);
|
|
|
|
|
|
if (m_preamble != null)
|
|
{
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (m_preamble);
|
|
os.write (l_bytebuf);
|
|
}
|
|
// Write the line "This is a multi-part message in MIME format".
|
|
// This needs to be done only if it is the body of the message. Not when it is
|
|
// embedded part of another part (like another multi-part or a Messagepart).
|
|
// This is accomplished by passing a flag to putByteStream() by Message class.
|
|
else if (m_needPreamble == true && m_parsedPart==0)
|
|
{
|
|
String l_preamble = new String ("\r\nThis is a multi-part message in MIME format\r\n");
|
|
// l_bytebuf = l_preamble.getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_preamble);
|
|
os.write (l_bytebuf);
|
|
m_needPreamble = false;
|
|
}
|
|
|
|
String l_trailBoundary = "\r\n" + "--" + l_boundary + "--" + "\r\n";
|
|
//l_boundary = "\r\n\r\n" + "--" + l_boundary + "\r\n";
|
|
l_boundary = "\r\n" + "--" + l_boundary + "\r\n";
|
|
//l_boundary = "--" + l_boundary + "\r\n";
|
|
|
|
for (int i = 0; i < l_bpCount; i++)
|
|
{
|
|
Object obj = m_bodyParts.elementAt (i);
|
|
|
|
if (obj instanceof MIMEBasicPart)
|
|
{
|
|
//l_bytebuf = l_boundary.getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_boundary);
|
|
os.write (l_bytebuf);
|
|
|
|
MIMEBasicPart part = (MIMEBasicPart) obj;
|
|
part.putByteStream (os);
|
|
}
|
|
else if (obj instanceof MIMEMessagePart)
|
|
{
|
|
//l_bytebuf = l_boundary.getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_boundary);
|
|
os.write (l_bytebuf);
|
|
|
|
MIMEMessagePart part = (MIMEMessagePart) obj;
|
|
part.putByteStream (os);
|
|
}
|
|
else if (obj instanceof MIMEMultiPart)
|
|
{
|
|
//l_bytebuf = l_boundary.getBytes("iso-8859-1");
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_boundary);
|
|
os.write (l_bytebuf);
|
|
|
|
MIMEMultiPart part = (MIMEMultiPart) obj;
|
|
part.putByteStream (os);
|
|
}
|
|
else
|
|
throw new MIMEException ("putByteStream(). Invalid bodyPart!");
|
|
|
|
} // end for
|
|
|
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_trailBoundary);
|
|
os.write (l_bytebuf);
|
|
}
|
|
|
|
/**
|
|
* Deletes bodyPart at the requested index from this Multipart.
|
|
* Adjusts indices of any parts after the deleted part upwards
|
|
* as needed.
|
|
* @param index of the bodyPart to remove.
|
|
* @exception MIMEException if invalid index.
|
|
*/
|
|
public void deleteBodyPart (int index) throws MIMEException
|
|
{
|
|
if (index > m_bodyParts.size())
|
|
throw new MIMEException ("deleteBodyPart(). Index out of range: " + index);
|
|
|
|
m_bodyParts.removeElementAt (index);
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds the specified filename file as a (MIMEBasicPart) BodyPart to this MultiPart.
|
|
* @param filename Name of file to add as bodyPart.
|
|
* @param encoding Preferred MIME encoding for this part. To select a default, use -1.
|
|
* @return The index at which this bodyPart is added.
|
|
* @see MIMEBodyPart#BASE64
|
|
* @see MIMEBodyPart#QP
|
|
* @see MIMEBodyPart#BINARY
|
|
* @see MIMEBodyPart#E7BIT
|
|
* @see MIMEBodyPart#E8BIT
|
|
* @exception MIMEException If filename file is inaccessible or I/O errors.
|
|
* @exception FileNotFoundException If filename file does not exist
|
|
* @exception SecurityException If filename file cannot be accessed
|
|
* @exception IOExcepton On IO Errors on filename
|
|
*/
|
|
public int addBodyPart (String filename, int encoding) throws MIMEException, FileNotFoundException, SecurityException, IOException
|
|
{
|
|
MIMEBasicPart l_filePart;
|
|
FileInputStream l_fis;
|
|
fileMIMEType l_fmt;
|
|
|
|
if (filename == null)
|
|
throw new MIMEException ("Invalid null filename:" + filename);
|
|
|
|
if ((encoding != -1) && (encoding < MIMEBodyPart.BASE64 || encoding > MIMEBodyPart.E8BIT))
|
|
|
|
throw new MIMEException ("Invalid MIME encoding:" + encoding);
|
|
|
|
l_fis = new FileInputStream (filename);
|
|
|
|
l_fmt = MIMEHelper.getFileMIMEType (filename);
|
|
|
|
if (l_fmt == null)
|
|
throw new MIMEException ("Can't determine MIME info for file: " + filename);
|
|
|
|
l_filePart = new MIMEBasicPart (l_fmt.content_type);
|
|
|
|
l_filePart.setContentSubType (l_fmt.content_subtype);
|
|
|
|
if (l_fmt.content_params != null)
|
|
l_filePart.setContentTypeParams (l_fmt.content_params);
|
|
else
|
|
l_filePart.setContentTypeParams (new String ("name=" + filename));
|
|
|
|
if (encoding == -1)
|
|
l_filePart.setContentEncoding (l_fmt.mime_encoding);
|
|
else
|
|
l_filePart.setContentEncoding (encoding);
|
|
|
|
if (l_fmt.content_type == MIMEBasicPart.TEXT)
|
|
l_filePart.setContentDisposition (MIMEBodyPart.INLINE);
|
|
else
|
|
{
|
|
l_filePart.setContentDisposition (MIMEBodyPart.ATTACHMENT);
|
|
l_filePart.setContentDispParams (new String ("filename=" + filename));
|
|
l_filePart.setContentDescription (filename);
|
|
}
|
|
|
|
// set body-data of this part
|
|
l_filePart.setBodyData (l_fis);
|
|
|
|
// Add this part to multi-part
|
|
return addBodyPart (l_filePart, false);
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a MIMEBodyPart to this MultiPart. This part must already be constructed
|
|
* and fully set-up. As MIMEBodyPart is an abstract class, the object passed in the
|
|
* part parameter must be one of three concrete classes: MIMEBasicPart, MIMEMultiPart, or
|
|
* MIMEMessagePart. If not, a MIMEException is thrown.
|
|
* @param part bodyPart to add.
|
|
* @param clone Whether to store a reference to the passed object instead of cloning a copy;
|
|
* if true: clones a copy; if false: stores reference to the passed part object.
|
|
* @return The index at which to add this bodyPart.
|
|
* @exception MIMEException If part is malformed or is not an object of one of three
|
|
* classes: MIMEBasicPart, MIMEMultiPart, or MIMEMessagePart.
|
|
* @see MIMEBasicPart
|
|
* @see MIMEMultiPart
|
|
* @see MIMEMessagePart
|
|
*/
|
|
public int addBodyPart (MIMEBodyPart part, boolean clone) throws MIMEException
|
|
{
|
|
if (part == null)
|
|
throw new MIMEException ("addBodyPart(): null part passed!");
|
|
|
|
if (part instanceof MIMEBasicPart)
|
|
return addBodyPart ((MIMEBasicPart) part, clone);
|
|
else if (part instanceof MIMEMessagePart)
|
|
return addBodyPart ((MIMEMessagePart) part, clone);
|
|
else if (part instanceof MIMEMultiPart)
|
|
return addBodyPart ((MIMEMultiPart) part, clone);
|
|
else
|
|
throw new MIMEException ("addBodyPart(): Invalid part ");
|
|
}
|
|
|
|
/**
|
|
* Adds a MIMEBasicPart BodyPart to this MultiPart. This part should have been
|
|
* constructed and fully set-up
|
|
* @param part bodyPart to add.
|
|
* @return The index at which this bodyPart is added.
|
|
* @exception MIMEException If it is a malformed bodyPart (or) can not be added.
|
|
* @see MIMEBasicPart
|
|
*/
|
|
protected int addBodyPart (MIMEBasicPart part ) throws MIMEException
|
|
{
|
|
return addBodyPart( part, true );
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a MIMEBasicPart BodyPart to this MultiPart. This part should have been
|
|
* constructed and fully set-up.
|
|
* @param part bodyPart to add.
|
|
* @return The index at which this bodyPart is added.
|
|
* @param clone if false stores reference to passed object instead of cloning a copy.
|
|
* @exception MIMEException If it is a malformed bodyPart (or) can not be added.
|
|
* @see MIMEBasicPart
|
|
*/
|
|
protected int addBodyPart (MIMEBasicPart part, boolean clone) throws MIMEException
|
|
{
|
|
MIMEBasicPart l_part;
|
|
|
|
if (part == null)
|
|
throw new MIMEException ("addBodyPart(): null part passed!");
|
|
|
|
if (clone)
|
|
{
|
|
try
|
|
{
|
|
l_part = (MIMEBasicPart) part.clone();
|
|
m_bodyParts.addElement (l_part);
|
|
}
|
|
catch (CloneNotSupportedException e)
|
|
{
|
|
throw new MIMEException (e.getMessage());
|
|
}
|
|
}
|
|
else
|
|
m_bodyParts.addElement (part);
|
|
|
|
return (m_bodyParts.size() -1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a MIMEBasicPart BodyPart to this MultiPart. This part should have been
|
|
* constructed and fully set-up
|
|
* @param part bodyPart to add.
|
|
* @return The index at which this bodyPart is added.
|
|
* @exception MIMEException If it is a malformed bodyPart (or) can not be added.
|
|
* @see MIMEBasicPart
|
|
*/
|
|
protected int addBodyPart (MIMEMultiPart part) throws MIMEException
|
|
{
|
|
return addBodyPart( part, true );
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a MIMEMultiPart BodyPart to this MultiPart. This part should have been
|
|
* constructed and fully set-up.
|
|
* @param part bodyPart to add.
|
|
* @param clone if false stores reference to passed object instead of cloning a copy.
|
|
* @return The index at which this bodyPart is added.
|
|
* @exception MIMEException If it is a malformed bodyPart (or) can not be added.
|
|
* clone made optional
|
|
*/
|
|
protected int addBodyPart (MIMEMultiPart part, boolean clone) throws MIMEException
|
|
{
|
|
MIMEMultiPart l_part;
|
|
|
|
if (part == null)
|
|
throw new MIMEException ("addBodyPart(): null part passed!");
|
|
|
|
if (clone)
|
|
{
|
|
try
|
|
{
|
|
l_part = (MIMEMultiPart) part.clone();
|
|
m_bodyParts.addElement (l_part );
|
|
}
|
|
catch (CloneNotSupportedException e)
|
|
{
|
|
throw new MIMEException (e.getMessage());
|
|
}
|
|
}
|
|
else
|
|
m_bodyParts.addElement (part);
|
|
|
|
return (m_bodyParts.size() -1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a MIMEBasicPart BodyPart to this MultiPart. This part should have been
|
|
* constructed and fully set-up.
|
|
* @param part bodyPart to add.
|
|
* @return The index at which this bodyPart is added.
|
|
* @exception MIMEException If it is a malformed bodyPart (or) can not be added.
|
|
* @see MIMEBasicPart
|
|
*/
|
|
protected int addBodyPart (MIMEMessagePart part) throws MIMEException
|
|
{
|
|
return addBodyPart( part, true );
|
|
}
|
|
|
|
/**
|
|
* Adds a MIMEMessagePart BodyPart to this MultiPart. This part should have been
|
|
* constructed and fully set-up.
|
|
* @param part bodyPart to add.
|
|
* @param clone if false stores reference to passed object instead of cloning a copy.
|
|
* @return The index at which this bodyPart is added.
|
|
* @exception MIMEException If it is a malformed bodyPart (or) can not be added.
|
|
*/
|
|
protected int addBodyPart (MIMEMessagePart part, boolean clone) throws MIMEException
|
|
{
|
|
MIMEMessagePart l_part;
|
|
|
|
if (part == null)
|
|
throw new MIMEException ("addBodyPart(): null part passed!");
|
|
|
|
if (clone)
|
|
{
|
|
try
|
|
{
|
|
l_part = (MIMEMessagePart) part.clone();
|
|
m_bodyParts.addElement (l_part);
|
|
}
|
|
catch (CloneNotSupportedException e)
|
|
{
|
|
throw new MIMEException (e.getMessage());
|
|
}
|
|
}
|
|
else
|
|
m_bodyParts.addElement (part);
|
|
|
|
return (m_bodyParts.size() -1);
|
|
}
|
|
|
|
protected void setContentEncoding (int encoding) //throws MIMEException
|
|
{
|
|
switch (encoding)
|
|
{
|
|
case BINARY:
|
|
case E7BIT:
|
|
case E8BIT:
|
|
m_contentTransferEncoding = encoding;
|
|
break;
|
|
default:
|
|
//throw new MIMEException ("Invalid Content Transfer Encoding : " + encoding);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the preamble for this multi-part if present.
|
|
* Returns null if preamble does not exist for this part.
|
|
* @return Preamble for the multi-part if present, null otherwise.
|
|
*/
|
|
public String getPreamble ()
|
|
{
|
|
return m_preamble;
|
|
}
|
|
|
|
/**
|
|
* Sets the preamble for this multi-part.
|
|
* @param preamble Preamble string.
|
|
*/
|
|
public void setPreamble (String preamble)
|
|
{
|
|
m_preamble = preamble;
|
|
}
|
|
|
|
protected void addPreamble (byte[] preamble, int len )
|
|
{
|
|
if (m_preamble == null)
|
|
m_preamble = new String (preamble, 0, len);
|
|
else
|
|
{
|
|
m_preamble = new String (m_preamble + new String (preamble, 0, len));
|
|
}
|
|
}
|
|
|
|
protected void addPreamble (byte[] preamble)
|
|
{
|
|
if (m_preamble == null)
|
|
m_preamble = new String (preamble);
|
|
else
|
|
{
|
|
m_preamble = new String (m_preamble + new String (preamble));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates and returns a boundary string that can be used in multi-parts etc.
|
|
* @return The boundary string.
|
|
*/
|
|
private String generateBoundary ()
|
|
{
|
|
Random l_rand = new Random (System.currentTimeMillis());
|
|
long l_numboundary = l_rand.nextLong();
|
|
String l_boundary = new String ("-----" + Long.toHexString(l_numboundary));
|
|
return (l_boundary);
|
|
}
|
|
|
|
|
|
/**
|
|
* Clones an instance of this MIMEMultiPart object.
|
|
* @exception CloneNotSupportedException If thrown by constituent components.
|
|
*/
|
|
public Object clone () throws CloneNotSupportedException
|
|
{
|
|
MIMEMultiPart l_theClone = (MIMEMultiPart) super.clone();
|
|
|
|
// Take care of all other "reference"s.
|
|
if (m_bodyParts != null)
|
|
l_theClone.m_bodyParts = (Vector) m_bodyParts.clone();
|
|
|
|
if (m_contentSubType != null)
|
|
l_theClone.m_contentSubType = m_contentSubType;
|
|
|
|
if (m_contentTypeParams != null)
|
|
l_theClone.m_contentTypeParams = m_contentTypeParams;
|
|
|
|
if (m_contentID != null)
|
|
l_theClone.m_contentID = m_contentID;
|
|
|
|
if (m_contentDispParams != null)
|
|
l_theClone.m_contentDispParams = m_contentDispParams;
|
|
|
|
if (m_contentDescription != null)
|
|
l_theClone.m_contentDescription = m_contentDescription;
|
|
|
|
m_needPreamble = false;
|
|
l_theClone.m_UserObject = m_UserObject;
|
|
|
|
return (l_theClone);
|
|
|
|
} // end clone ()
|
|
|
|
|
|
// Should not be exposed at the API level. Internal only routines.
|
|
protected void setBoundary( String boundary )
|
|
{
|
|
if ( boundary != null )
|
|
m_boundary = boundary;
|
|
}
|
|
|
|
protected String getBoundary() { return m_boundary; }
|
|
|
|
} // end class MIMEMultiPart
|