Mozilla/mozilla/msgsdk/java/highlevel/src/IMTransport.java
dmose%mozilla.org 9fc7780ead updating license boilerplate to xPL v1.1
git-svn-id: svn://10.0.0.236/trunk@52523 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 06:20:05 +00:00

702 lines
19 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.convenience;
import java.io.*;
import java.lang.*;
import java.util.*;
import netscape.messaging.smtp.*;
import netscape.messaging.mime.*;
/**
* The IMTransport class implements Java Convenience APIs.
* <p>This class provides a convenient interface for building,
* encoding, and sending messages. It combines the functionality
* of MIME and SMTP.
* @author Prasad Yendluri
*/
public class IMTransport
{
/**
* Content (primary) type Text.
*/
public static final int TEXT = 0;
/**
* Content (primary) type Audio.
*/
public static final int AUDIO = 1;
/**
* Content (primary) type Image.
*/
public static final int IMAGE = 2;
/**
* Content (primary) type Video.
*/
public static final int VIDEO = 3;
/**
* Content (primary) type Application.
*/
public static final int APPLICATION = 4;
/**
* Base64 Transfer Encoding.
*/
public static final int BASE64 = 0;
/**
* Quoted Printable Transfer Encoding.
*/
public static final int QP = 1;
/**
* No Transfer Encoding.
*/
public static final int NONE = 2;
/**
* Content disposition INLINE
*/
public static final int INLINE = 1;
/**
* Content disposition ATTACHMENT
*/
public static final int ATTACHMENT = 2;
/**
* Default constructor for the IMTransport class.
*/
//public IMTransport ()
//{
// // Do any initialization
//}
/**
* Connects to the SMTP transport at the specified host and submits the message.
* <P>NOTE: The MIME Message itself can be created using the Netscape MIME API or
* by any other means.
* @param host Name of the host to connect to.
* @param sender Sender of the message.
* @param recipients Email addresses of the recipients of the message, separated by commas or spaces.
* @param MIMEMessageStream Input-Stream to the message in MIME canonical form.
* @return List of recipients to whom the message could not be submitted.
* @exception IMException If the message could not be sent due to invalid host
* or other causes.
* @see #sendDocuments
*/
public static String [] sendMessage (String host,
String sender,
String recipients,
InputStream MIMEMessageStream) throws IMException
{
Vector l_rejrecips;
SMTPClient l_SMTPclnt;
IMSMTPSink l_smtpSink;
String[] l_addrs=null;
if (sender == null || sender.length() == 0)
{
throw new IMException ("Invalid null sender");
}
if (host == null || host.length() == 0)
{
throw new IMException ("Invalid null host");
}
if (MIMEMessageStream == null)
{
throw new IMException ("Invalid InputStream");
}
if (recipients != null)
l_addrs = parseAddrs (recipients);
if (l_addrs == null || l_addrs.length <= 0)
{
throw new IMException ("Invalid recipients");
}
if (recipients != null)
l_addrs = parseAddrs (recipients);
if (l_addrs == null || l_addrs.length <= 0)
{
throw new IMException ("Invalid recipients");
}
try {
l_smtpSink = new IMSMTPSink();
l_SMTPclnt = new SMTPClient (l_smtpSink);
l_SMTPclnt.connect (host);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("Unable to connect to SMTP host " + host);
}
l_SMTPclnt.mailFrom (sender, null);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("sender rejected by server. Resp Code = " +
l_smtpSink.m_failCode);
}
boolean someFailed = false;
boolean allFailed = true;
l_rejrecips = new Vector();
for (int i = 0, len = l_addrs.length; i < len; i++)
{
l_SMTPclnt.rcptTo (l_addrs[i], null);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
someFailed = true;
l_rejrecips.addElement (l_addrs[i]);
}
else
allFailed = false;
}
if (allFailed)
{
throw new IMException ("Server rejected all recipients");
}
l_SMTPclnt.setChunkSize (8192);
l_SMTPclnt.data ();
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("Unable to intiate Data transfer with server. Resp Code = " +
l_smtpSink.m_failCode);
}
l_SMTPclnt.send (MIMEMessageStream);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("Data transfer failure! Resp Code = " +
l_smtpSink.m_failCode);
}
l_SMTPclnt.quit();
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
// Ignore!
//showFailPopUp("Error!", "Unbale to quit from server! Server code = "
// + l_smtpSink.m_failCode);
}
if (someFailed == true)
{
if (l_rejrecips == null)
return null;
String [] rejrecips = new String [l_rejrecips.size()];
for (int i=0; i < l_rejrecips.size(); i++)
{
rejrecips [i] = (String) l_rejrecips.elementAt (i);
}
return (rejrecips);
}
else
{
return null;
}
}
catch (IOException e)
{
throw new IMException (e.getMessage());
}
}
protected static String [] sendMessage2 (String host,
String sender,
String recipients,
PipedInputStream MIMEMessageStream) throws IMException
{
Vector l_rejrecips;
SMTPClient l_SMTPclnt;
IMSMTPSink l_smtpSink;
String[] l_addrs=null;
if (sender == null || sender.length() == 0)
{
throw new IMException ("Invalid null sender");
}
if (host == null || host.length() == 0)
{
throw new IMException ("Invalid null host");
}
if (MIMEMessageStream == null)
{
throw new IMException ("Invalid InputStream");
}
if (recipients != null)
l_addrs = parseAddrs (recipients);
if (l_addrs == null || l_addrs.length <= 0)
{
throw new IMException ("Invalid recipients");
}
if (recipients != null)
l_addrs = parseAddrs (recipients);
if (l_addrs == null || l_addrs.length <= 0)
{
throw new IMException ("Invalid recipients");
}
try {
l_smtpSink = new IMSMTPSink();
l_SMTPclnt = new SMTPClient (l_smtpSink);
l_SMTPclnt.connect (host);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("Unable to connect to SMTP host " + host);
}
l_SMTPclnt.mailFrom (sender, null);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("sender rejected by server. Resp Code = " +
l_smtpSink.m_failCode);
}
boolean someFailed = false;
boolean allFailed = true;
l_rejrecips = new Vector();
for (int i = 0, len = l_addrs.length; i < len; i++)
{
l_SMTPclnt.rcptTo (l_addrs[i], null);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
someFailed = true;
l_rejrecips.addElement (l_addrs[i]);
}
else
allFailed = false;
}
if (allFailed)
{
throw new IMException ("Server rejected all recipients");
}
l_SMTPclnt.data ();
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("Unable to intiate Data transfer with server. Resp Code = " +
l_smtpSink.m_failCode);
}
l_SMTPclnt.send (MIMEMessageStream);
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
throw new IMException ("Data transfer failure! Resp Code = " +
l_smtpSink.m_failCode);
}
l_SMTPclnt.quit();
if (!l_smtpSink.tryProcessResponses(l_SMTPclnt))
{
// Ignore!
//showFailPopUp("Error!", "Unbale to quit from server! Server code = "
// + l_smtpSink.m_failCode);
}
if (someFailed == true)
{
if (l_rejrecips == null)
return null;
String [] rejrecips = new String [l_rejrecips.size()];
for (int i=0; i < l_rejrecips.size(); i++)
{
rejrecips [i] = (String) l_rejrecips.elementAt (i);
}
return (rejrecips);
}
else
{
return null;
}
}
catch (IOException e)
{
throw new IMException (e.getMessage());
}
}
/**
* Builds a MIME message with the specified parameters. Connects to the SMTP transport
* at the specified host and submits the message. If the message has more than one
* attachment, it is sent as MIME multipart/mixed type message.
* <P>NOTE: This method facilitates mailing documents by mail-enabling an otherwise
* mail-ignorant application. For any other uses or more sophisticated needs,
* use the sendMessage() method in association with the Netscape MIME API
* or the other Messaging APIs provided by Netscape.
* <P>NOTE: If the fUseTempFiles parameter is set to true, sendDocuments uses
* temporary intermediate files for some internal processing. This mode provides better
* performance. If temporary files should not be created, set this flag to false.
* @param host Name of the host to connect to.
* @param sender Sender of the message.
* @param recipients Email addresses of the recipients of the message, separated by commas or spaces.
* @param subject Subject of the Message. Can be null.
* @param msgHeaderNames Additional RFC-822 header names.
* @param msgHeaderValues Values corresponding to the headers in the msgHeaderNames parameter.
* @param fUseTempFiles Whether to use temporary intermediate files for some
* internal processing. Values:
* <ul><li>true: use temp files (better performance).
* <li>false: do not use temp files. </ul>
* @param fUseTempFiles If true, uses temporary intermediate files (for better performance).
* @return List of recipients to whom the message could not be submitted.
* @exception IMException If the message could not be sent due to invalid host or other
* causes, or if there are inconsistencies in the parameter specifications.
*/
public static String [] sendDocuments (String host,
String sender,
String recipients,
String subject,
String[] msgHeaderNames,
String[] msgHeaderValues,
IMAttachment [] attachments,
boolean fUseTempFiles) throws IMException
{
MIMEMultiPart l_mmp;
MIMEBasicPart l_mbp;
MIMEMessage l_mmsg;
boolean fMultiPart = false;
//boolean fUseTempFiles = true;
int attach_count = 0, hdrs_count = 0;
//FileInputStream l_fis;
String [] rejrecips;
String m_mimefile;
Vector l_rejects;
if (sender == null || sender.length() == 0)
{
throw new IMException ("Invalid null sender");
}
if (host == null || host.length() == 0)
{
throw new IMException ("Invalid null host");
}
if (recipients == null)
{
throw new IMException ("Invalid null recipients");
}
if (msgHeaderNames != null)
{
hdrs_count = msgHeaderNames.length;
if (msgHeaderValues == null || hdrs_count != msgHeaderValues.length)
{
throw new IMException ("msgHeaderNames and msgHeaderValues not equal in number");
}
}
else
hdrs_count = 0;
if (attachments == null || attachments.length == 0)
{
throw new IMException ("Invalid null attachments");
}
attach_count = attachments.length;
if (attach_count > 1)
fMultiPart = true;
try
{
l_mmp = new MIMEMultiPart ();
l_mmp.setContentSubType ("mixed");
for (int i = 0; i < attach_count; i++)
{
// build and add each attach to the message
if (attachments [i] != null)
{
//System.out.println("sendDocuments()> doing buildBasicPart. i= " + i);
l_mbp = buildBasicPart (attachments[i]);
l_mmp.addBodyPart (l_mbp, false);
}
}
l_mmsg = new MIMEMessage ();
l_mmsg.setBody (l_mmp, false);
if (hdrs_count > 0)
for (int i = 0; i < hdrs_count; i++)
{
l_mmsg.setHeader (msgHeaderNames[i], msgHeaderValues [i]);
}
if (subject != null)
l_mmsg.setHeader ("Subject", subject);
if (fUseTempFiles == true)
{
// set up default tmpdir
String sep, tmpdir;
sep = System.getProperty ("path.separator");
if (sep.equals (";"))
tmpdir = "C:\\temp\\"; // its windoz
else
tmpdir = "/tmp/";
Random l_rand = new Random (System.currentTimeMillis());
long l_decrand = l_rand.nextLong();
m_mimefile = new String (tmpdir + Long.toHexString(l_decrand));
removeFile (m_mimefile);
FileOutputStream fos = new FileOutputStream (m_mimefile);
l_mmsg.putByteStream (fos);
FileInputStream l_fis = new FileInputStream (m_mimefile);
rejrecips = sendMessage (host, sender, recipients, l_fis);
removeFile (m_mimefile);
return rejrecips;
}
else
{
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pins = new PipedInputStream(pos);
l_rejects = new Vector();
IMSendThr sendThr = new IMSendThr (pins, host, sender,
recipients, l_rejects);
sendThr.start();
//System.out.println("SendDocs> l_mmsg.putByteStream()");
l_mmsg.putByteStream (pos);
//System.out.println("SendDocs> pos.close()");
pos.close();
//System.out.println("SendDocs> doinigIMSendThr.join()!");
sendThr.join();
if (l_rejects == null)
return null;
rejrecips = new String [l_rejects.size()];
for (int i=0; i < l_rejects.size(); i++)
{
rejrecips [i] = (String) l_rejects.elementAt (i);
}
return rejrecips;
}
}
catch (Exception e)
{
e.printStackTrace();
throw new IMException (e.getMessage());
}
}
protected static void removeFile(String in_file)
{
if (in_file != null)
{
File file = new File(in_file);
if (file.exists())
file.delete();
}
}
protected static MIMEBasicPart buildBasicPart (IMAttachment attachment) throws MIMEException, IMException, IOException
{
fileMIMEType l_fmt;
MIMEBasicPart l_basicPart;
int content_type;
String content_subtype;
String content_params;
int content_disposition;
int mime_encoding = NONE;
InputStream dataIS;
if (attachment.attach_file != null)
{
if (attachment.attach_stream != null)
{
throw new IMException ("Invalid attachment");
}
l_fmt = MIMEHelper.getFileMIMEType (attachment.attach_file);
if (l_fmt == null)
throw new IMException ("Invalid attachment");
if (attachment.content_type >= TEXT && attachment.content_type <= APPLICATION)
{
//System.out.println("buildBasicPart()> setting content-type from passed in");
content_type = attachment.content_type;
content_subtype = attachment.content_subtype;
content_params = attachment.content_params;
}
else
{
//System.out.println("buildBasicPart()> setting content-type from getFileMIMEType() = " + l_fmt.content_type + " sub-type" + l_fmt.content_subtype + " params=" + l_fmt.content_params);
content_type = l_fmt.content_type;
content_subtype = l_fmt.content_subtype;
content_params = l_fmt.content_params;
}
if (l_fmt.mime_encoding != BASE64)
{
if (attachment.mime_encoding >= BASE64 && attachment.mime_encoding < NONE)
mime_encoding = attachment.mime_encoding;
else
mime_encoding = l_fmt.mime_encoding;
}
else
mime_encoding = l_fmt.mime_encoding;
FileInputStream fis = new FileInputStream (attachment.attach_file);
dataIS = fis;
}
else
{
dataIS = attachment.attach_stream;
if (attachment.content_type >= TEXT && attachment.content_type <= APPLICATION)
{
content_type = attachment.content_type;
content_subtype = attachment.content_subtype;
content_params = attachment.content_params;
if (attachment.mime_encoding >= BASE64 && attachment.mime_encoding < NONE)
mime_encoding = attachment.mime_encoding;
else
mime_encoding = BASE64;
}
else
{
content_type = APPLICATION;
content_subtype = new String ("octet-stream");
content_params = null;
mime_encoding = BASE64;
}
}
if (attachment.content_disposition == INLINE ||
attachment.content_disposition == ATTACHMENT)
{
content_disposition = attachment.content_disposition;
}
else
content_disposition = INLINE;
l_basicPart = new MIMEBasicPart(content_type);
if (content_subtype != null)
l_basicPart.setContentSubType (content_subtype);
if (content_params != null)
l_basicPart.setContentTypeParams (content_params);
if (attachment.content_disposition > -1)
l_basicPart.setContentDisposition (attachment.content_disposition);
l_basicPart.setBodyData (dataIS);
//new
if (mime_encoding == BASE64)
l_basicPart.setContentEncoding (MIMEBodyPart.BASE64);
else if (mime_encoding == QP)
l_basicPart.setContentEncoding (MIMEBodyPart.QP);
return l_basicPart;
}
////////////////////////////////////////////////////////////////
// Parse space or comma separated addresses
///////////////////////////////////////////////////////////////
protected static String [] parseAddrs (String mailAddrs)
{
String [] retAddrs;
int count;
String inAddrs = mailAddrs.trim();
StringTokenizer stz = new StringTokenizer (inAddrs, " ,");
count = stz.countTokens();
if (count <= 0)
return null;
retAddrs = new String [count];
for (int i = 0; i < count; i++)
{
retAddrs [i] = stz.nextToken();
}
return retAddrs;
}
}