/* * 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. *

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. *

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. *

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. *

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: *

* @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; } }