зеркало из https://github.com/mozilla/pjs.git
adding new sources
This commit is contained in:
Родитель
b10d52ff43
Коммит
25e803bf0c
|
@ -0,0 +1,13 @@
|
||||||
|
This directory contains an example program that demonstrates the use of the Netscape
|
||||||
|
Messaging MIME Encoder java API.
|
||||||
|
|
||||||
|
To compile and run:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
(1) Make sure CLASSPATH includes the msg-sdk jar file (proapi.jar).
|
||||||
|
When installed proapi.jar is located at <install-root>/packages/proapi.jar.
|
||||||
|
Make sure CLASSPATH also includes the directory you are compiling in.
|
||||||
|
|
||||||
|
(2) Compile: javac *.java
|
||||||
|
(3) Run: java <class-name>
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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): ______________________________________.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example program for MIME Encoder API.
|
||||||
|
* Demonstrates how to create messages with MessagePart content
|
||||||
|
*/
|
||||||
|
public class TestMessagePart
|
||||||
|
{
|
||||||
|
private static final int MultiPart = 10;
|
||||||
|
private static final int MessagePart = 11;
|
||||||
|
private static String tmpdir;
|
||||||
|
|
||||||
|
public TestMessagePart ()
|
||||||
|
{
|
||||||
|
String sep = System.getProperty ("path.separator");
|
||||||
|
|
||||||
|
if (sep.equals (";"))
|
||||||
|
tmpdir = "C:\\temp\\";
|
||||||
|
else
|
||||||
|
tmpdir = "/tmp/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setOtherHeaders (MIMEMessage mmsg)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mmsg.setHeader ("From", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("To", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("CC", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("Reply-To", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("X-MyTest-Header", "Test-Header-1");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("setOtherHeader> Caught exception: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create a text-part
|
||||||
|
public MIMEBasicPart createTextPart (String inText)
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_mbp;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_mbp = new MIMEBasicPart (MIMEBasicPart.TEXT);
|
||||||
|
l_mbp.setContentSubType ("plain");
|
||||||
|
l_mbp.setContentTypeParams ("charset=us-ascii");
|
||||||
|
l_mbp.setContentID("Text_BasicPart_ContentID");
|
||||||
|
//l_mbp.setContentEncoding(MIMEBodyPart.E7BIT);
|
||||||
|
l_mbp.setContentDisposition(MIMEBodyPart.INLINE);
|
||||||
|
//l_mbp.setContentDisposition(MIMEBodyPart.ATTACHMENT); // if you like
|
||||||
|
l_mbp.setContentDispParams("TextPart Disp-Params");
|
||||||
|
l_mbp.setContentDispParams("Some_Params");
|
||||||
|
l_mbp.setHeader ("X-TextPartHeader-1", "myValue-1");
|
||||||
|
l_mbp.setHeader ("X-TextPartHeader-2", "myValue-2");
|
||||||
|
l_mbp.setBodyData (inText);
|
||||||
|
|
||||||
|
return l_mbp;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("createTextPart Caught exception: " + e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a message
|
||||||
|
public MIMEMessage createMessage () throws MIMEException
|
||||||
|
{
|
||||||
|
MIMEMessage l_msg;
|
||||||
|
|
||||||
|
// create a blank message
|
||||||
|
l_msg = new MIMEMessage();
|
||||||
|
|
||||||
|
// create a text part
|
||||||
|
MIMEBasicPart l_txtPart = createTextPart ("Hello this is a simple text part");
|
||||||
|
|
||||||
|
// set the text part as body of the message
|
||||||
|
l_msg.setBody (l_txtPart, false); // false implies don't clone the part
|
||||||
|
|
||||||
|
// set some headers on the message
|
||||||
|
l_msg.setHeader ("Subject", "Inner Text Message");
|
||||||
|
l_msg.setHeader ("From", "Prasad Yendluri <prasad@mcom.com>");
|
||||||
|
l_msg.setHeader ("To", "Prasad Yendluri <prasad@mcom.com>");
|
||||||
|
l_msg.setHeader ("Reply-To", "Prasad Yendluri <prasad@mcom.com>");
|
||||||
|
l_msg.setHeader ("X-Hdr-Inner", "Some Value");
|
||||||
|
|
||||||
|
// we are done. Return the created message
|
||||||
|
return l_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a message part
|
||||||
|
public MIMEMessagePart createMessagePart ()
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_msgpart;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// first create the message that goes in the message part
|
||||||
|
MIMEMessage l_msg = createMessage ();
|
||||||
|
|
||||||
|
// Create a message part w/ above message
|
||||||
|
l_msgpart = new MIMEMessagePart (l_msg);
|
||||||
|
|
||||||
|
// set any attributes on the messagePart
|
||||||
|
l_msgpart.setContentDescription ("This is a forwarded message");
|
||||||
|
l_msgpart.setContentDisposition (MIMEBodyPart.INLINE);
|
||||||
|
l_msgpart.setContentEncoding (MIMEBodyPart.E7BIT); // default E7BIT
|
||||||
|
//l_msgpart.setContentSubType ("rfc822"); // default rfc822
|
||||||
|
|
||||||
|
return l_msgpart;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("createMsgPartExt Caught exception: " + e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
MIMEMessage mmsg;
|
||||||
|
MIMEMessagePart mmsgpart;
|
||||||
|
FileOutputStream fos;
|
||||||
|
TestMessagePart tm = new TestMessagePart ();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create a message part
|
||||||
|
mmsgpart = tm.createMessagePart ();
|
||||||
|
|
||||||
|
// Create a new Message with this messagePart.
|
||||||
|
MIMEMessage msg = new MIMEMessage ();
|
||||||
|
|
||||||
|
// set the above messagePart as body of the message
|
||||||
|
msg.setBody (mmsgpart, false);
|
||||||
|
|
||||||
|
// Set headers of the new Message
|
||||||
|
msg.setHeader ("Subject", "Test Message w/ MessagePart Body");
|
||||||
|
setOtherHeaders (msg);
|
||||||
|
|
||||||
|
// MIME encode the created message
|
||||||
|
fos = new FileOutputStream (tmpdir + "MsgWithMessagePart.out");
|
||||||
|
msg.putByteStream (fos);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("Caught exception: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // main()
|
||||||
|
|
||||||
|
} // TestMessagePart
|
|
@ -0,0 +1,13 @@
|
||||||
|
This directory contains an example program that demonstrates the use of the Netscape
|
||||||
|
Messaging MIME Encoder java API.
|
||||||
|
|
||||||
|
To compile and run:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
(1) Make sure CLASSPATH includes the msg-sdk jar file (proapi.jar).
|
||||||
|
When installed proapi.jar is located at <install-root>/packages/proapi.jar.
|
||||||
|
Make sure CLASSPATH also includes the directory you are compiling in.
|
||||||
|
|
||||||
|
(2) Compile: javac *.java
|
||||||
|
(3) Run: java <class-name>
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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): ______________________________________.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example program for MIME Encoder API.
|
||||||
|
* Demonstrates how to create messages with message/external-body content.
|
||||||
|
*/
|
||||||
|
public class TestExtBodyMessagePart
|
||||||
|
{
|
||||||
|
private static final int MultiPart = 10;
|
||||||
|
private static final int MessagePart = 11;
|
||||||
|
private static String tmpdir;
|
||||||
|
|
||||||
|
public TestExtBodyMessagePart ()
|
||||||
|
{
|
||||||
|
String sep = System.getProperty ("path.separator");
|
||||||
|
|
||||||
|
if (sep.equals (";"))
|
||||||
|
tmpdir = "C:\\temp\\";
|
||||||
|
else
|
||||||
|
tmpdir = "/tmp/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setOtherHeaders (MIMEMessage mmsg)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
mmsg.setHeader ("From", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("To", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("CC", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("Reply-To", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("X-MyTest-Header", "Test-Header-1");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("setOtherHeader> Caught exception: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
MIMEMessage mmsg;
|
||||||
|
MIMEMessagePart mmsgpart;
|
||||||
|
FileOutputStream fos;
|
||||||
|
TestExtBodyMessagePart tm = new TestExtBodyMessagePart ();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
System.out.println ("Creating Message w/ External Body");
|
||||||
|
|
||||||
|
// Create a message part
|
||||||
|
System.out.println ("Creating MessagePart");
|
||||||
|
mmsgpart = new MIMEMessagePart ();
|
||||||
|
|
||||||
|
// set the attributes of the messagePart
|
||||||
|
mmsgpart.setContentSubType ("external-body");
|
||||||
|
mmsgpart.setContentTypeParams ("access-type=local-file;name=\"e:\\share\\jpeg1.jpg\"");
|
||||||
|
mmsgpart.setContentEncoding (MIMEBodyPart.E7BIT);
|
||||||
|
|
||||||
|
// set ext-part headers
|
||||||
|
mmsgpart.setExtBodyHeader ("Content-Type", "image/jpg");
|
||||||
|
|
||||||
|
// Create a new Message with this messagePart.
|
||||||
|
System.out.println ("Creating a new Message ");
|
||||||
|
MIMEMessage msg = new MIMEMessage ();
|
||||||
|
|
||||||
|
System.out.println ("Setting the above MessagePart as body of this Message.");
|
||||||
|
msg.setBody (mmsgpart, false);
|
||||||
|
|
||||||
|
System.out.println ("Setting headers in the new Message");
|
||||||
|
msg.setHeader ("Subject", "Test Message w/ external MessagePart Body");
|
||||||
|
|
||||||
|
System.out.println ("Setting other headers in the new Message");
|
||||||
|
setOtherHeaders (msg);
|
||||||
|
|
||||||
|
fos = new FileOutputStream (tmpdir + "MsgWithExtBodyMessagePart.out");
|
||||||
|
System.out.println ("Writing message to output Stream");
|
||||||
|
msg.putByteStream (fos);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("Caught exception: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // main()
|
||||||
|
|
||||||
|
} // TestExtBodyMessagePart
|
|
@ -0,0 +1,13 @@
|
||||||
|
This directory contains an example program that demonstrates the use of the Netscape
|
||||||
|
Messaging MIME Encoder java API.
|
||||||
|
|
||||||
|
To compile and run:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
(1) Make sure CLASSPATH includes the msg-sdk jar file (proapi.jar).
|
||||||
|
When installed proapi.jar is located at <install-root>/packages/proapi.jar.
|
||||||
|
Make sure CLASSPATH also includes the directory you are compiling in.
|
||||||
|
|
||||||
|
(2) Compile: javac *.java
|
||||||
|
(3) Run: java <class-name>
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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): ______________________________________.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example program for MIME Encoder API.
|
||||||
|
* Demonstrates how to create messages with multipart content from scratch.
|
||||||
|
* Please note that the classes MIMEMessage and MIMEMultiPart contain
|
||||||
|
* convenience methods to create a multi-part message with two parts, in a
|
||||||
|
* simple and single step. Please see other MIME examples provided for that
|
||||||
|
* purpose. This example demonstrates how to build a multi-part message from
|
||||||
|
* ground up.
|
||||||
|
*/
|
||||||
|
public class TestMultiPartMessage
|
||||||
|
{
|
||||||
|
private static String tmpdir;
|
||||||
|
|
||||||
|
public TestMultiPartMessage ()
|
||||||
|
{
|
||||||
|
String sep = System.getProperty ("path.separator");
|
||||||
|
|
||||||
|
if (sep.equals (";"))
|
||||||
|
tmpdir = "C:\\temp\\";
|
||||||
|
else
|
||||||
|
tmpdir = "/tmp/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setOtherHeaders (MIMEMessage mmsg)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mmsg.setHeader ("From", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("To", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("CC", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("Reply-To", "Prasad Yendluri <prasad@netscape.com>");
|
||||||
|
mmsg.setHeader ("X-MyTest-Header", "Test-Header-1");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("setOtherHeader> Caught exception: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a message part w/ external-body
|
||||||
|
public MIMEMessagePart createMsgPartExt ()
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_msgpart;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create a message part
|
||||||
|
l_msgpart = new MIMEMessagePart ();
|
||||||
|
|
||||||
|
// set the attributes of the messagePart
|
||||||
|
l_msgpart.setContentSubType ("external-body");
|
||||||
|
l_msgpart.setContentTypeParams ("access-type=local-file;name=\"e:\\share\\jpeg1.jpg\"");
|
||||||
|
l_msgpart.setContentEncoding (MIMEBodyPart.E7BIT);
|
||||||
|
|
||||||
|
// set ext-part headers
|
||||||
|
l_msgpart.setExtBodyHeader ("Content-Type", "image/jpg");
|
||||||
|
|
||||||
|
return l_msgpart;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("createMsgPartExt Caught exception: " + e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create a text-part
|
||||||
|
public MIMEBasicPart createTextPart (String inText)
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_mbp;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_mbp = new MIMEBasicPart (MIMEBasicPart.TEXT);
|
||||||
|
l_mbp.setContentSubType ("plain");
|
||||||
|
l_mbp.setContentTypeParams ("charset=us-ascii");
|
||||||
|
l_mbp.setContentID("Text_BasicPart_ContentID");
|
||||||
|
//l_mbp.setContentEncoding(MIMEBodyPart.E7BIT);
|
||||||
|
l_mbp.setContentDisposition(MIMEBodyPart.INLINE);
|
||||||
|
//l_mbp.setContentDisposition(MIMEBodyPart.ATTACHMENT); // if you like
|
||||||
|
l_mbp.setContentDispParams("TextPart Disp-Params");
|
||||||
|
l_mbp.setContentDispParams("Some_Description");
|
||||||
|
l_mbp.setHeader ("X-TextPartHeader-1", "myValue-1");
|
||||||
|
l_mbp.setHeader ("X-TextPartHeader-2", "myValue-2");
|
||||||
|
l_mbp.setBodyData (inText);
|
||||||
|
|
||||||
|
return l_mbp;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("createTextPart Caught exception: " + e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create a basic-part from the filename passed
|
||||||
|
public MIMEBasicPart createFilePart (String filename, int encoding)
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_filePart;
|
||||||
|
FileInputStream l_fis;
|
||||||
|
fileMIMEType l_fmt;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get the mime-type info on the file passed
|
||||||
|
l_fmt = MIMEHelper.getFileMIMEType (filename);
|
||||||
|
if (l_fmt == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// create a new basic-part for the file and set the attributes
|
||||||
|
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); // need sanity check on encoding
|
||||||
|
|
||||||
|
l_filePart.setContentDispParams (new String ("filename=" + l_fmt.file_shortname));
|
||||||
|
l_filePart.setContentDescription (l_fmt.file_shortname);
|
||||||
|
|
||||||
|
// open input-stream to the file
|
||||||
|
l_fis = new FileInputStream (filename);
|
||||||
|
|
||||||
|
// set the stream as body-data
|
||||||
|
l_filePart.setBodyData (l_fis);
|
||||||
|
|
||||||
|
// all done. Return the part
|
||||||
|
return l_filePart;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("createTextPart Caught exception: " + e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
MIMEMessage mmsg;
|
||||||
|
MIMEMultiPart mmp;
|
||||||
|
MIMEBasicPart bpText, bpFile;
|
||||||
|
MIMEMessagePart mmsgpart;
|
||||||
|
FileOutputStream fos;
|
||||||
|
TestMultiPartMessage tm = new TestMultiPartMessage ();
|
||||||
|
String filename = null;
|
||||||
|
int encoding = -1;
|
||||||
|
|
||||||
|
if (args.length < 1)
|
||||||
|
{
|
||||||
|
System.out.println("usage: java TestMultiPartMessage <file-name> <B|Q>");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = args[0];
|
||||||
|
|
||||||
|
if (args.length > 1)
|
||||||
|
{
|
||||||
|
if (args[1].equalsIgnoreCase("B"))
|
||||||
|
encoding = MIMEBodyPart.BASE64;
|
||||||
|
|
||||||
|
if (args[1].equalsIgnoreCase("Q"))
|
||||||
|
encoding = MIMEBodyPart.QP;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create the MultiPart w/ mixed subtype
|
||||||
|
mmp = new MIMEMultiPart ();
|
||||||
|
mmp.setContentSubType ("mixed"); // You could use other subtypes (e.g."alternate") here
|
||||||
|
mmp.setContentTypeParams ("test-params");
|
||||||
|
|
||||||
|
// create a text-part (basic-part) and add it to the multi-part
|
||||||
|
bpText = tm.createTextPart ("Hello this a simple text part.");
|
||||||
|
if (bpText != null)
|
||||||
|
mmp.addBodyPart (bpText, false); // flase => don't clone it
|
||||||
|
|
||||||
|
// create a basic-part from the file-name passed and add it to the multi-part
|
||||||
|
bpFile = tm.createFilePart (filename, encoding);
|
||||||
|
|
||||||
|
if (bpFile != null)
|
||||||
|
{
|
||||||
|
mmp.addBodyPart (bpFile, false); // flase => don't clone it
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a message part (external-body)
|
||||||
|
mmsgpart = tm.createMsgPartExt ();
|
||||||
|
|
||||||
|
if (bpFile != null)
|
||||||
|
mmp.addBodyPart (mmsgpart, false); // flase => don't clone it
|
||||||
|
|
||||||
|
// o.k we now have a multi-part w/ three parts
|
||||||
|
// make a MIMEMessage out of it.
|
||||||
|
mmsg = new MIMEMessage ();
|
||||||
|
mmsg.setBody (mmp, false);
|
||||||
|
|
||||||
|
// Set needed headers of the new Message
|
||||||
|
mmsg.setHeader ("Subject", "Test Message w/ MultiPart content");
|
||||||
|
|
||||||
|
// Set other headers of the Message
|
||||||
|
setOtherHeaders (mmsg);
|
||||||
|
|
||||||
|
// Now the message is completely built!
|
||||||
|
// Encode it in MIME canonical form
|
||||||
|
fos = new FileOutputStream (tmpdir + "MsgWithMultiPart.out");
|
||||||
|
mmsg.putByteStream (fos);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println ("Caught exception: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // main()
|
||||||
|
|
||||||
|
} // TestMultiPartMessage
|
|
@ -0,0 +1,312 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.InputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutable subclass of ByteString.
|
||||||
|
*/
|
||||||
|
public final class ByteBuffer extends ByteString implements Cloneable {
|
||||||
|
boolean wasCloned;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ByteBuffer of the given capacity
|
||||||
|
*/
|
||||||
|
public ByteBuffer (int capacity) {
|
||||||
|
super();
|
||||||
|
buffer = new byte[capacity];
|
||||||
|
wasCloned = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ByteBuffer of the given capacity
|
||||||
|
*/
|
||||||
|
public ByteBuffer (ByteString bs) {
|
||||||
|
super();
|
||||||
|
buffer = bs.buffer;
|
||||||
|
hi = bs.hi;
|
||||||
|
lo = bs.lo;
|
||||||
|
wasCloned = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ByteBuffer of the given capacity
|
||||||
|
* no clone version
|
||||||
|
*/
|
||||||
|
public ByteBuffer (byte[] b)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
buffer = b;
|
||||||
|
hi = b.length;
|
||||||
|
lo = 0;
|
||||||
|
wasCloned = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ByteBuffer of the given capacity
|
||||||
|
* no clone version
|
||||||
|
*/
|
||||||
|
public ByteBuffer (byte[] b, int len)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
buffer = b;
|
||||||
|
hi = len;
|
||||||
|
lo = 0;
|
||||||
|
wasCloned = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure there is capacity for appending num bytes.
|
||||||
|
*/
|
||||||
|
private final void ensureCapacity (int num) {
|
||||||
|
byte[] newBuffer = null;
|
||||||
|
int newsize;
|
||||||
|
|
||||||
|
if (hi == lo) erase();
|
||||||
|
if (buffer.length - hi >= num) return;
|
||||||
|
|
||||||
|
newsize = num + (hi-lo);
|
||||||
|
if (newsize*2 < buffer.length) {
|
||||||
|
newsize = buffer.length;
|
||||||
|
if (!wasCloned) newBuffer = buffer;
|
||||||
|
}
|
||||||
|
else if (newsize < buffer.length*2) newsize = buffer.length*2;
|
||||||
|
|
||||||
|
if (newBuffer == null)
|
||||||
|
newBuffer = new byte[newsize];
|
||||||
|
|
||||||
|
System.arraycopy(buffer, lo, newBuffer, 0, hi-lo );
|
||||||
|
|
||||||
|
buffer = newBuffer;
|
||||||
|
wasCloned = false;
|
||||||
|
hi -= lo;
|
||||||
|
lo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a ByteString. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void append (ByteString that) {
|
||||||
|
ensureCapacity(that.size());
|
||||||
|
System.arraycopy(that.buffer, that.lo, this.buffer, this.hi, that.size());
|
||||||
|
this.hi += that.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a substring of a ByteString. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void append (ByteString that, int start) {
|
||||||
|
int substrSize = that.size() - start;
|
||||||
|
|
||||||
|
if (substrSize < 0) throw new IndexOutOfBoundsException();
|
||||||
|
ensureCapacity(substrSize);
|
||||||
|
System.arraycopy(that.buffer, that.lo+start, this.buffer, this.hi,
|
||||||
|
substrSize);
|
||||||
|
this.hi += substrSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a substring of a ByteString. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void append (ByteString that, int start, int finish) {
|
||||||
|
if (start > finish || finish > that.size())
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
ensureCapacity(finish - start);
|
||||||
|
System.arraycopy(that.buffer, that.lo+start, this.buffer, this.hi, finish-start);
|
||||||
|
this.hi += (finish-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a byte[]. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void append (byte[] that) {
|
||||||
|
ensureCapacity(that.length);
|
||||||
|
System.arraycopy(that, 0, this.buffer, this.hi, that.length);
|
||||||
|
this.hi += that.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a byte[]. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void append (byte[] that, int len )
|
||||||
|
{
|
||||||
|
ensureCapacity(len);
|
||||||
|
System.arraycopy(that, 0, this.buffer, this.hi, len);
|
||||||
|
this.hi += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a long
|
||||||
|
*/
|
||||||
|
public final void append (long n) {
|
||||||
|
ensureCapacity(8);
|
||||||
|
for (int i=hi+8; --i>=hi; ) {
|
||||||
|
buffer[i] = (byte)(n & 0xff);
|
||||||
|
n >>= 8;
|
||||||
|
}
|
||||||
|
hi += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an int
|
||||||
|
*/
|
||||||
|
public final void append (int n) {
|
||||||
|
ensureCapacity(4);
|
||||||
|
for (int i=hi+4; --i>=hi; ) {
|
||||||
|
buffer[i] = (byte)(n & 0xff);
|
||||||
|
n >>= 8;
|
||||||
|
}
|
||||||
|
hi += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a byte
|
||||||
|
*/
|
||||||
|
public final void append (byte n) {
|
||||||
|
ensureCapacity(1);
|
||||||
|
buffer[hi] = n;
|
||||||
|
hi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase the contents of the ByteBuffering. Not MT safe.
|
||||||
|
* Will not shrink capacity.
|
||||||
|
*/
|
||||||
|
public final void erase () {
|
||||||
|
if (!wasCloned) hi = 0;
|
||||||
|
lo = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defragment the contents of buffer. Not MT safe.
|
||||||
|
*/
|
||||||
|
public final void cleanup () {
|
||||||
|
if (wasCloned || lo+lo <= buffer.length)
|
||||||
|
return;
|
||||||
|
System.arraycopy(buffer, lo, buffer, 0, hi-lo);
|
||||||
|
hi -= lo;
|
||||||
|
lo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return substring from offset start (inclusive) till offset
|
||||||
|
* finish (exclusive).
|
||||||
|
*/
|
||||||
|
public ByteString substring (int start, int finish) {
|
||||||
|
ByteString result = super.substring(start, finish);
|
||||||
|
wasCloned = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return substring to the right of the given offset (inclusive).
|
||||||
|
*/
|
||||||
|
public ByteString substring (int start) {
|
||||||
|
ByteString result = super.substring(start);
|
||||||
|
wasCloned = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a line. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void addLine (ByteString line) {
|
||||||
|
append(line);
|
||||||
|
append(CRLF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a line. Not MT-safe.
|
||||||
|
*/
|
||||||
|
public final void addLine (byte[] line) {
|
||||||
|
append(line);
|
||||||
|
append(CRLF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a line read (and maybe more) from a stream. Not MT-safe.
|
||||||
|
* Blocks until one line is read. May read multiple lines.
|
||||||
|
*/
|
||||||
|
public final void readLine (InputStream stream)
|
||||||
|
throws IOException {
|
||||||
|
while (noLines()) {
|
||||||
|
bulkRead(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk read from a stream. Not MT-safe.
|
||||||
|
* Returns the number of bytes read.
|
||||||
|
*/
|
||||||
|
public final int bulkRead (InputStream stream)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
int n = -1;
|
||||||
|
ensureCapacity(1024); // TODO: is this a good number?
|
||||||
|
for (int attempt = 0; attempt < 10; attempt++) {
|
||||||
|
n = stream.read(buffer, hi, buffer.length-hi);
|
||||||
|
if (n > 0) {
|
||||||
|
hi += n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
else if (n == 0) {
|
||||||
|
System.err.println("BufferedInputStream.read(byte[], int, int) returns 0 on attempt #" + attempt);
|
||||||
|
try {
|
||||||
|
Thread.sleep(500);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.err.println(e + " while waiting in bulkRead");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IOException("Bulk read returns " + n + " bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IOException("Bulk read returns " + n + " bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones an instance of the ByteBuffer object.
|
||||||
|
* @exception CloneNotSupportedException could be thrown by constituent components.
|
||||||
|
*/
|
||||||
|
public Object clone () throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
ByteBuffer l_theClone = (ByteBuffer) super.clone();
|
||||||
|
|
||||||
|
return (l_theClone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getInputStream()
|
||||||
|
{
|
||||||
|
return new ByteArrayInputStream( buffer, lo, hi );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize( int len ) { ensureCapacity( len ); }
|
||||||
|
}
|
|
@ -0,0 +1,501 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.BufferedOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ByteString is similar to java.lang.String, except that it contains
|
||||||
|
* bytes instead of characters.
|
||||||
|
*/
|
||||||
|
public class ByteString extends Object implements Cloneable {
|
||||||
|
protected byte[] buffer;
|
||||||
|
protected int lo;
|
||||||
|
protected int hi;
|
||||||
|
|
||||||
|
protected static byte CR = '\r';
|
||||||
|
protected static byte LF = '\n';
|
||||||
|
protected static byte[] CRLF = "\r\n".getBytes();
|
||||||
|
|
||||||
|
protected ByteString () {
|
||||||
|
buffer = null;
|
||||||
|
lo = 0;
|
||||||
|
hi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteString (String string) {
|
||||||
|
buffer = string.getBytes();
|
||||||
|
lo = 0;
|
||||||
|
hi = buffer.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteString (byte[] buffer) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
this.lo = 0;
|
||||||
|
this.hi = buffer.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteString (byte[] buffer, int lo, int hi) {
|
||||||
|
if (lo > hi) throw new IndexOutOfBoundsException();
|
||||||
|
this.buffer = buffer;
|
||||||
|
this.lo = lo;
|
||||||
|
this.hi = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hashCode() -- Overrides java.lang.Object.hashCode()
|
||||||
|
*/
|
||||||
|
public final int hashCode () {
|
||||||
|
int result = 0;
|
||||||
|
// TODO: improve hash function
|
||||||
|
for (int i = lo; i < hi; i++) {
|
||||||
|
result += buffer[i];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* equals() -- Overrides java.lang.Object.equals()
|
||||||
|
*/
|
||||||
|
public final boolean equals (Object that) {
|
||||||
|
if (this == that)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return equals(((ByteString) that).buffer, ((ByteString) that).lo, ((ByteString) that).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean equals (byte[] buf) {
|
||||||
|
return equals(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean equals (byte[] buf, int low, int length) {
|
||||||
|
|
||||||
|
if (this.size() != length)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (this.byteAt(i) != buf[low++])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare this to that in lex order
|
||||||
|
*/
|
||||||
|
public final boolean greaterOrEqual (ByteString that) {
|
||||||
|
int m = this.size();
|
||||||
|
int n = that.size();
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (i >= m)
|
||||||
|
return false;
|
||||||
|
else {
|
||||||
|
byte x = this.byteAt(i);
|
||||||
|
byte y = that.byteAt(i);
|
||||||
|
if (x < y)
|
||||||
|
return false;
|
||||||
|
else if (x > y)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return number of bytes
|
||||||
|
*/
|
||||||
|
public final int size () {
|
||||||
|
return (hi-lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return byte at given offset.
|
||||||
|
*/
|
||||||
|
public final byte byteAt (int i) {
|
||||||
|
if (lo + i >= hi) throw new IndexOutOfBoundsException();
|
||||||
|
return buffer[lo+i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the ByteString starts with the given byte[].
|
||||||
|
* Ignores case.
|
||||||
|
*/
|
||||||
|
private final boolean startsWith (byte[] that) {
|
||||||
|
if (that.length > hi - lo) return false;
|
||||||
|
for (int i = 0; i < that.length; i++) {
|
||||||
|
char x = (char)(buffer[lo+i]);
|
||||||
|
char y = (char)(that[i]);
|
||||||
|
if (x != y && (x < 'a' || x > 'z' || (x + 'A' - 'a') != y))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the offset for the first occurrence of a given byte
|
||||||
|
* in the ByteString if present, and -1 otherwise.
|
||||||
|
*/
|
||||||
|
public final int firstIndexOf (byte x) {
|
||||||
|
for (int i = lo; i < hi; i++) {
|
||||||
|
if (buffer[i] == x)
|
||||||
|
return (i-lo);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the offset for the first occurrence of a given byte
|
||||||
|
* in the ByteString to the right of the given offset if present, and
|
||||||
|
* -1 otherwise.
|
||||||
|
*/
|
||||||
|
public final int firstIndexOf (byte x, int offset) {
|
||||||
|
for (int i = lo+offset+1; i < hi; i++) {
|
||||||
|
if (buffer[i] == x)
|
||||||
|
return (i-lo);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the offset for the last occurrence of a given byte
|
||||||
|
* in the ByteString if present, and -1 otherwise.
|
||||||
|
*/
|
||||||
|
public final int lastIndexOf (byte x) {
|
||||||
|
for (int i = hi; --i >= lo; ) {
|
||||||
|
if (buffer[i] == x)
|
||||||
|
return (i-lo);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the offset for the last occurrence of a given byte
|
||||||
|
* in the ByteString to the left of the given offset if present, and
|
||||||
|
* -1 otherwise.
|
||||||
|
*/
|
||||||
|
public final int lastIndexOf (byte x, int offset) {
|
||||||
|
for (int i = lo+offset; --i >= lo; ) {
|
||||||
|
if (buffer[i] == x)
|
||||||
|
return (i-lo);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the offset for the first occurrence of a given byte[]
|
||||||
|
* in the ByteString to the right of the given offset if present,
|
||||||
|
* and -1 otherwise. Case insensitive.
|
||||||
|
*/
|
||||||
|
public final int firstIndexOf (byte[] that) {
|
||||||
|
return firstIndexOf(that, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the offset for the first occurrence of a given byte[]
|
||||||
|
* in the ByteString to the right of the given offset if present,
|
||||||
|
* and -1 otherwise. Case insensitive.
|
||||||
|
*/
|
||||||
|
public final int firstIndexOf (byte[] that, int offset) {
|
||||||
|
|
||||||
|
for (int i = lo+offset; i <= hi-that.length; i++) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < that.length; j++) {
|
||||||
|
char x = (char)(buffer[i+j]);
|
||||||
|
char y = (char)(that[j]);
|
||||||
|
if (x != y && (x < 'a' || x > 'z' || (x + 'A' - 'a') != y))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j >= that.length) {
|
||||||
|
return i-lo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to String
|
||||||
|
*/
|
||||||
|
public final String toString () {
|
||||||
|
return new String(buffer, lo, hi-lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to byte[]
|
||||||
|
* clone version
|
||||||
|
*/
|
||||||
|
public final byte[] getBytes () { return getBytes( true ); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to byte[]
|
||||||
|
* clonable version
|
||||||
|
*/
|
||||||
|
public final byte[] getBytes ( boolean clone )
|
||||||
|
{
|
||||||
|
if ( clone )
|
||||||
|
{
|
||||||
|
byte[] result = new byte[hi-lo];
|
||||||
|
System.arraycopy(buffer, lo, result, 0, hi-lo);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final byte[] getBytes ( int len[] )
|
||||||
|
{
|
||||||
|
len[0] = hi;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract X out of ByteString X+Y+Z, where Y is the given delimiter.
|
||||||
|
* Replace original ByteString (X+Y+Z) by Z. Not MT-safe.
|
||||||
|
* Returns null if Y is absent.
|
||||||
|
*/
|
||||||
|
public final ByteString extractTill (byte[] y) {
|
||||||
|
int offset = firstIndexOf(y, 0);
|
||||||
|
if (offset < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ByteString result = substring(0, offset);
|
||||||
|
lo += (offset + y.length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Y from ByteString Y+Z, where Y is the given token,
|
||||||
|
* If successful, replace original ByteString (Y+Z) by Z, and
|
||||||
|
* & return true. Else return false. Not MT-safe.
|
||||||
|
* Throw ArrayIndexOutOfBoundsException if ByteString does
|
||||||
|
* not start with Y.
|
||||||
|
*/
|
||||||
|
public final boolean extractToken (byte[] y) {
|
||||||
|
if (startsWith(y)) {
|
||||||
|
lo += y.length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discard COUNT bytes from ByteString
|
||||||
|
*/
|
||||||
|
public final void discard(int count) {
|
||||||
|
if (lo + count > hi) throw new IndexOutOfBoundsException();
|
||||||
|
lo += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discard X+Y from ByteString X+Y+Z, where Y is the given token.
|
||||||
|
* Throw ArrayIndexOutOfBoundsException if Y is absent.
|
||||||
|
*/
|
||||||
|
public final void discardTill (byte[] y) {
|
||||||
|
lo += (firstIndexOf(y, 0) + y.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discard X+Y from ByteString X+Y+Z, where Y is LF or CRLF.
|
||||||
|
* Throw ArrayIndexOutOfBoundsException if Y is absent.
|
||||||
|
*/
|
||||||
|
public final void discardLine () {
|
||||||
|
lo += (firstIndexOf(LF, 0) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for absence of complete lines
|
||||||
|
*/
|
||||||
|
public final boolean noLines () {
|
||||||
|
return firstIndexOf(LF, 0) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for absence of complete lines to the right of the given offset
|
||||||
|
*/
|
||||||
|
public final boolean noLines (int offset) {
|
||||||
|
return firstIndexOf(LF, offset) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the first line and return it as a substring.
|
||||||
|
* Throw ArrayIndexOutOfBoundsException if there are no lines.
|
||||||
|
*/
|
||||||
|
public final ByteString extractLine() {
|
||||||
|
ByteString result;
|
||||||
|
int offset = firstIndexOf(LF, 0);
|
||||||
|
if (offset > 1 && byteAt(offset-1) == CR) {
|
||||||
|
result = substring(0, offset-1);
|
||||||
|
lo += (offset + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = substring(0, offset);
|
||||||
|
lo += (offset + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the first line and write it to given output stream.
|
||||||
|
* Throw ArrayIndexOutOfBoundsException if there are no lines.
|
||||||
|
* return number of byte wrote
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final int extractLine(OutputStream stream)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
int origin = lo;
|
||||||
|
|
||||||
|
int offset = firstIndexOf(LF, 0);
|
||||||
|
if (offset > 1 && byteAt(offset-1) == CR) {
|
||||||
|
stream.write(buffer, lo, offset-1);
|
||||||
|
stream.write(CRLF);
|
||||||
|
lo += (offset + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stream.write(buffer, lo, offset);
|
||||||
|
stream.write(CRLF);
|
||||||
|
lo += (offset + 1);
|
||||||
|
}
|
||||||
|
return (lo - origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void discardLeadingSpace()
|
||||||
|
{
|
||||||
|
// skip leading space
|
||||||
|
for (; lo < hi; lo++) {
|
||||||
|
if (buffer[lo] != ' ' )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bulk write to a stream.
|
||||||
|
*/
|
||||||
|
public final void write (OutputStream stream)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
stream.write(buffer, lo, hi-lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract a long
|
||||||
|
**/
|
||||||
|
public final long extractLong() {
|
||||||
|
long n = 0;
|
||||||
|
for (int i = lo; i < lo+8; i++) {
|
||||||
|
n <<= 8;
|
||||||
|
n += buffer[i];
|
||||||
|
}
|
||||||
|
lo += 8;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract an int
|
||||||
|
**/
|
||||||
|
public final int extractInt() {
|
||||||
|
int n = 0;
|
||||||
|
for (int i = lo; i < lo+4; i++) {
|
||||||
|
n <<= 8;
|
||||||
|
n += buffer[i];
|
||||||
|
}
|
||||||
|
lo += 4;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return substring from offset start (inclusive) till offset
|
||||||
|
* finish (exclusive).
|
||||||
|
*/
|
||||||
|
public ByteString substring (int start, int finish) {
|
||||||
|
if (start > finish || lo+finish > hi)
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
return new ByteString(buffer, lo+start, lo+finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return substring from offset start (inclusive) till the
|
||||||
|
* end of the ByteString.
|
||||||
|
*/
|
||||||
|
public ByteString substring (int start) {
|
||||||
|
if (lo+start > hi) throw new IndexOutOfBoundsException();
|
||||||
|
return new ByteString(buffer, lo+start, hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the contents of the ByteString for
|
||||||
|
* the purpose of debugging
|
||||||
|
*/
|
||||||
|
public void displayBuffer (String caption, BufferedOutputStream stream) {
|
||||||
|
int saved = lo;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; !noLines(); i++) {
|
||||||
|
stream.write(caption.getBytes());
|
||||||
|
extractLine(stream);
|
||||||
|
}
|
||||||
|
stream.write(caption.getBytes());
|
||||||
|
stream.write(getBytes());
|
||||||
|
lo = saved;
|
||||||
|
stream.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e + " while displaying contents of ByteString");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones an instance of the ByteString object.
|
||||||
|
* @exception CloneNotSupportedException could be thrown by constituent components.
|
||||||
|
*/
|
||||||
|
public Object clone () throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
ByteString l_theClone = (ByteString) super.clone();
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
l_theClone.buffer = new byte [buffer.length];
|
||||||
|
System.arraycopy (buffer, 0, l_theClone.buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (l_theClone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setSize( int len )
|
||||||
|
{
|
||||||
|
hi = len;
|
||||||
|
lo = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Header class is used to represent the Header of the message.
|
||||||
|
* @author Prasad Yendluri
|
||||||
|
*/
|
||||||
|
public class Header implements Cloneable
|
||||||
|
{
|
||||||
|
protected String m_headerName;
|
||||||
|
private String m_headerValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header constructor.
|
||||||
|
* Creates a Header object given header name and value strings.
|
||||||
|
* @param name Name of the header.
|
||||||
|
* @param value Value of the header.
|
||||||
|
* @exception MIMEException If either name or value is null.
|
||||||
|
*/
|
||||||
|
public Header (String name, String value) throws MIMEException
|
||||||
|
{
|
||||||
|
if (name == null || value == null)
|
||||||
|
throw new MIMEException ("Inavlid null <name> (or) <value>.");
|
||||||
|
|
||||||
|
m_headerName = name;
|
||||||
|
m_headerValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header constructor.
|
||||||
|
* Creates a Header object given a string in <name>:<value> format.
|
||||||
|
* Any '\r' and '\n' chars at the end of the line are stripped.
|
||||||
|
* All the chars in inStr must map to ASCII.
|
||||||
|
* @param inStr. A String with header in the form <name>:<value>
|
||||||
|
* @exception MIMEException If inStr is null or not in <name>:<value> form.
|
||||||
|
*/
|
||||||
|
public Header (String inStr) throws MIMEException
|
||||||
|
{
|
||||||
|
int sepIndex = 0, strLen;
|
||||||
|
|
||||||
|
if (inStr == null)
|
||||||
|
throw new MIMEException ("String in <name>:<value> form expected.");
|
||||||
|
|
||||||
|
inStr.trim();
|
||||||
|
|
||||||
|
strLen = inStr.length();
|
||||||
|
|
||||||
|
while (strLen > 0)
|
||||||
|
{
|
||||||
|
if ((inStr.lastIndexOf ('\n', strLen-1) > 0) ||
|
||||||
|
(inStr.lastIndexOf ('\r', strLen-1) > 0))
|
||||||
|
strLen--;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strLen <= 3)
|
||||||
|
throw new MIMEException ("String in <name>:<value> form expected.");
|
||||||
|
|
||||||
|
sepIndex = inStr.indexOf (':');
|
||||||
|
|
||||||
|
if ((sepIndex == 0) || (sepIndex == strLen-1))
|
||||||
|
throw new MIMEException ("String in <name>:<value> form expected.");
|
||||||
|
|
||||||
|
m_headerName = inStr.substring (0, sepIndex);
|
||||||
|
m_headerValue = inStr.substring (sepIndex+1, strLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header constructor.
|
||||||
|
* Creates a Header object given a byte array with header in the form <name>:<value>.
|
||||||
|
* Any '\r' and '\n' chars at the end of the line are stripped.
|
||||||
|
* All the chars in line[] must be ASCII.
|
||||||
|
* @param line. A byte array with header in the form <name>:<value>
|
||||||
|
* @exception MIMEException If line is null or not in <name>:<value> form.
|
||||||
|
*/
|
||||||
|
public Header (byte[] line) throws MIMEException
|
||||||
|
{
|
||||||
|
int linelen, sepIndex = 0;
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
|
throw new MIMEException ("byte[] in <name>:<value> form expected.");
|
||||||
|
|
||||||
|
linelen = line.length;
|
||||||
|
|
||||||
|
// Trim trailing spaces and CR LFs.
|
||||||
|
while ((linelen > 0) && ((line [linelen-1] == '\n') ||
|
||||||
|
(line [linelen-1] == '\r') || (line [linelen-1] == ' ')))
|
||||||
|
linelen--;
|
||||||
|
|
||||||
|
// NOTE: No need to check for leading spaces as we trim Name and Value anyway.
|
||||||
|
|
||||||
|
if (linelen <= 3)
|
||||||
|
throw new MIMEException ("byte[] in <name>:<value> form expected.");
|
||||||
|
|
||||||
|
for (int i = 0; i < linelen; i++)
|
||||||
|
{
|
||||||
|
if (line [i] == ':')
|
||||||
|
{
|
||||||
|
sepIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sepIndex == 0) || (sepIndex == linelen-1))
|
||||||
|
throw new MIMEException ("byte[] in <name>:<value> form expected.");
|
||||||
|
|
||||||
|
m_headerName = new String (line, 0, sepIndex);
|
||||||
|
m_headerValue = new String (line, sepIndex+1, (linelen - (sepIndex +1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this header.
|
||||||
|
*/
|
||||||
|
public String getName ()
|
||||||
|
{
|
||||||
|
return (m_headerName.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of this header.
|
||||||
|
*/
|
||||||
|
public String getValue ()
|
||||||
|
{
|
||||||
|
return (m_headerValue.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of this header.
|
||||||
|
* @param name Name of the header to set.
|
||||||
|
*/
|
||||||
|
protected void setName ( String name ) throws MIMEException
|
||||||
|
{
|
||||||
|
if (name == null)
|
||||||
|
throw new MIMEException ("Inavlid null <name> (or) <value>.");
|
||||||
|
|
||||||
|
m_headerName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of this header.
|
||||||
|
* @param value Value of the header to set.
|
||||||
|
*/
|
||||||
|
protected void setValue ( String value ) throws MIMEException
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new MIMEException ("Inavlid null <name> (or) <value>.");
|
||||||
|
|
||||||
|
m_headerValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the compelete header-line in the form <Name>: <Value> with CRLF termination.
|
||||||
|
*/
|
||||||
|
public String getLine ()
|
||||||
|
{
|
||||||
|
String line;
|
||||||
|
line = new String (m_headerName.trim() + ": " + m_headerValue.trim() + "\r\n");
|
||||||
|
return (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones an instance of the Header object.
|
||||||
|
*/
|
||||||
|
public Object clone ()
|
||||||
|
{
|
||||||
|
Header l_theClone;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_theClone = (Header) super.clone();
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_headerName != null)
|
||||||
|
l_theClone.m_headerName = m_headerName;
|
||||||
|
if (m_headerValue != null)
|
||||||
|
l_theClone.m_headerValue = m_headerValue;
|
||||||
|
|
||||||
|
return (l_theClone);
|
||||||
|
}
|
||||||
|
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The MIMEBodyPart class represents a body-part of a MIME message.
|
||||||
|
* MIMEBodyPart is the base class for all MIME BodyPart classes:
|
||||||
|
* MIMEBasicPart, MIMEMessagePart, and MIMEMultiPart.
|
||||||
|
* @author Prasad Yendluri
|
||||||
|
*/
|
||||||
|
public abstract class MIMEBodyPart implements Cloneable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Content Disposition is Attachment.
|
||||||
|
*/
|
||||||
|
public static final int ATTACHMENT = 0;
|
||||||
|
/**
|
||||||
|
* Content Disposition is inline.
|
||||||
|
*/
|
||||||
|
public static final int INLINE = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64 Transfer Encoding.
|
||||||
|
*/
|
||||||
|
public static final int BASE64 = 0;
|
||||||
|
/**
|
||||||
|
* Quoted Printable Transfer Encoding.
|
||||||
|
*/
|
||||||
|
public static final int QP = 1;
|
||||||
|
/**
|
||||||
|
* Binary Data with No Transfer Encoding.
|
||||||
|
*/
|
||||||
|
public static final int BINARY = 2;
|
||||||
|
/**
|
||||||
|
* 7bit Data with No Transfer Encoding.
|
||||||
|
*/
|
||||||
|
public static final int E7BIT = 3;
|
||||||
|
/**
|
||||||
|
* 8bit Data with No Transfer Encoding.
|
||||||
|
*/
|
||||||
|
public static final int E8BIT = 4;
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Internal members not visible at the API
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
public static final int UNINITIALIZED = -1;
|
||||||
|
protected static final int DATABUFSZ = 8192;
|
||||||
|
protected static final int HDRBUFSZ = 1024;
|
||||||
|
|
||||||
|
protected String m_contentSubType;
|
||||||
|
protected String m_contentTypeParams;
|
||||||
|
protected String m_contentID;
|
||||||
|
protected int m_contentDisposition;
|
||||||
|
protected String m_contentDispParams;
|
||||||
|
protected String m_contentDescription;
|
||||||
|
|
||||||
|
protected static final byte[] CRLF = "\r\n".getBytes();
|
||||||
|
protected static final byte[] LF = "\n".getBytes();
|
||||||
|
protected Object m_UserObject;
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// get() and set() Methods
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-Type of this MIME Part.
|
||||||
|
* Note: The primary content-type is determined by the
|
||||||
|
* actual MIMEPart class and thus cannot be set.
|
||||||
|
* @return String containing the Content-Type or
|
||||||
|
* NULL if Content-Type cannot be determined.
|
||||||
|
*/
|
||||||
|
public abstract String getContentType ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content SubType of this MIME Part.
|
||||||
|
* @return String containing the Content-SubType or
|
||||||
|
* NULL if Content-SubType cannot be determined.
|
||||||
|
*/
|
||||||
|
public String getContentSubType ()
|
||||||
|
{
|
||||||
|
if (m_contentSubType == null)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
return (m_contentSubType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Content SubType of this MIME Part.
|
||||||
|
* Note: The primary content-type is determined by the
|
||||||
|
* actual MIMEPart class and thus cannot be set.
|
||||||
|
* @param subType String to use as sub-type for this part.
|
||||||
|
* @exception MIMEException If the subtype parameter is null.
|
||||||
|
*/
|
||||||
|
public void setContentSubType (String subType) throws MIMEException
|
||||||
|
{
|
||||||
|
// It is client's responsibility to check the consistency with content-type etc.
|
||||||
|
// We can not really enforce this as, new sub-types can be added any time.
|
||||||
|
|
||||||
|
if (subType != null)
|
||||||
|
m_contentSubType = subType;
|
||||||
|
else
|
||||||
|
throw new MIMEException ("Invalid null Content-SubType");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-Type Parameters of this MIME Part.
|
||||||
|
* @return String containing the Content-Type Parameters or
|
||||||
|
* NULL if no parameters exist.
|
||||||
|
*/
|
||||||
|
public String getContentTypeParams ()
|
||||||
|
{
|
||||||
|
if (m_contentTypeParams == null)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
return (m_contentTypeParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Content-Type Parameters of this MIME Part.
|
||||||
|
* @param params String to use as Content-Type Parameters.
|
||||||
|
*/
|
||||||
|
public void setContentTypeParams (String params)
|
||||||
|
{
|
||||||
|
// It is client's responsibility to check the consistency with content-type etc.
|
||||||
|
// We can not really enforce this as, new kind of params can be added any time.
|
||||||
|
|
||||||
|
if (params != null)
|
||||||
|
m_contentTypeParams = params;
|
||||||
|
else
|
||||||
|
m_contentTypeParams = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-ID of this MIME Part.
|
||||||
|
* @return String containing the Content-ID Parameters or
|
||||||
|
* NULL if none is present.
|
||||||
|
*/
|
||||||
|
public String getContentID ()
|
||||||
|
{
|
||||||
|
if (m_contentID == null)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
return (m_contentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Content-ID of this MIME Part.
|
||||||
|
* @param cid String to use as Content-ID.
|
||||||
|
*/
|
||||||
|
public void setContentID (String cid)
|
||||||
|
{
|
||||||
|
if (cid != null)
|
||||||
|
m_contentID = cid;
|
||||||
|
else
|
||||||
|
m_contentID = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-Disposition of this MIME Part.
|
||||||
|
* @return Content-Disposition of this MIME Part or
|
||||||
|
* -1 if none present.
|
||||||
|
* @see MIMEBodyPart#ATTACHMENT
|
||||||
|
* @see MIMEBodyPart#INLINE
|
||||||
|
*/
|
||||||
|
public int getContentDisposition ()
|
||||||
|
{
|
||||||
|
if (m_contentDisposition == UNINITIALIZED)
|
||||||
|
return (-1);
|
||||||
|
else
|
||||||
|
return (m_contentDisposition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Content-Disposition of this MIME Part.
|
||||||
|
* @param disposition Value of the Content-Disposition. Must be ATTACHMENT or INLINE.
|
||||||
|
* @see MIMEBodyPart#ATTACHMENT
|
||||||
|
* @see MIMEBodyPart#INLINE
|
||||||
|
* @exception MIMEException If invalid disposition value is passed.
|
||||||
|
*/
|
||||||
|
public void setContentDisposition (int disposition) throws MIMEException
|
||||||
|
{
|
||||||
|
if ((disposition != MIMEBodyPart.ATTACHMENT) && (disposition != MIMEBodyPart.INLINE))
|
||||||
|
{
|
||||||
|
throw new MIMEException ("Invalid ContentDisposition: " + disposition);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_contentDisposition = disposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-Disposition Parameters of this MIME Part.
|
||||||
|
* @return String containing the Content Disposition Parameters or
|
||||||
|
* NULL if none exist.
|
||||||
|
*/
|
||||||
|
public String getContentDispParams ()
|
||||||
|
{
|
||||||
|
if (m_contentDispParams == null)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
return (m_contentDispParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Content-Disposition Parameters of this MIME Part.
|
||||||
|
* @param params String to be used as Content-Disposition Parameters.
|
||||||
|
*/
|
||||||
|
public void setContentDispParams (String params)
|
||||||
|
{
|
||||||
|
if (params != null)
|
||||||
|
m_contentDispParams = params;
|
||||||
|
else
|
||||||
|
m_contentDispParams = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-Description of this MIME Part. NULL if none present.
|
||||||
|
*/
|
||||||
|
public String getContentDescription ()
|
||||||
|
{
|
||||||
|
if (m_contentDescription == null)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
return (m_contentDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Content-Description of this MIME Part.
|
||||||
|
* @param description String to be used as Content-Description.
|
||||||
|
*/
|
||||||
|
public void setContentDescription (String description)
|
||||||
|
{
|
||||||
|
if (description != null)
|
||||||
|
m_contentDescription = description;
|
||||||
|
else
|
||||||
|
m_contentDescription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone () throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
return (super.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getUserObject() { return m_UserObject; }
|
||||||
|
protected void setUserObject( Object userObject ) { m_UserObject = userObject; }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The MIMEDataSink class represents the DataSink that implements
|
||||||
|
* callbacks. Clients can subclass from this abstract class.
|
||||||
|
* @author Carson Lee
|
||||||
|
*/
|
||||||
|
abstract public class MIMEDataSink
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
public MIMEDataSink ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies header information.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param name Name of the header.
|
||||||
|
* @param value Value of the header.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void header (Object callbackObject, byte[] name, byte[] value ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies additional value for a header.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param name Name of the header.
|
||||||
|
* @param value Value of the header.
|
||||||
|
* @see #header
|
||||||
|
*/
|
||||||
|
public void addHeader (Object callbackObject, byte[] name, byte[] value ){}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to indicate end of headers on the top level message.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #header
|
||||||
|
*/
|
||||||
|
public void endMessageHeader (Object callbackObject){}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies contentType information.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param nContentType Content type.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
//public void contentType( Object callbackObject, int nBodyPartType){}
|
||||||
|
public void contentType( Object callbackObject, byte[] contentType){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies contentSubType information.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param contentSubType Content subtype.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentSubType( Object callbackObject, byte[] contentSubType ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies contentTypeParams.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param contentTypeParams Content type parameters.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentTypeParams( Object callbackObject, byte[] contentTypeParams ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies ContentID.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param contentID Content identifier.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentID( Object callbackObject, byte[] ContentID ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies contentMD5.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param contentMD5 Content MD5 information.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentMD5( Object callbackObject, byte[] contentMD5 ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies ContentDisposition.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param nContentDisposition Content Disposition type.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentDisposition( Object callbackObject, int nContentDisposition ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies contentDispParams.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param contentDispParams Content Disposition parameters.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentDispParams( Object callbackObject, byte[] contentDispParams ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies contentDescription.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param contentDescription Content Description.
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentDescription( Object callbackObject, byte[] contentDescription ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that supplies ContentEncoding.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param nContentEncoding Content Encoding type. For values, see "MIME Encoding Types."
|
||||||
|
* @see #startMessage
|
||||||
|
* @see #startBasicPart
|
||||||
|
* @see #startMultiPart
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void contentEncoding( Object callbackObject, int nContentEncoding ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates start of a new MIMEMessage.
|
||||||
|
* No reference to MIMEMessage object is kept internally.
|
||||||
|
* @return Object Client-supplied opaque object to be passed to subsequent callbacks.
|
||||||
|
* @see #endMessage
|
||||||
|
*/
|
||||||
|
public Object startMessage(){ return null; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates end of MIMEMessage.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @see #startMessage
|
||||||
|
*/
|
||||||
|
public void endMessage(Object callbackObject) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates start of a new MIMEBasicPart.
|
||||||
|
* No reference to MIMEBasicPart object is kept internally.
|
||||||
|
* @return Object Client-supplied opaque object to be passed to subsequent callbacks.
|
||||||
|
* @see #endBasicPart
|
||||||
|
*/
|
||||||
|
public Object startBasicPart(){ return null; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No reference to MIMEBasicPart object is kept internally.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param input Input stream for body data.
|
||||||
|
* @param len Length of buffer
|
||||||
|
*/
|
||||||
|
public void bodyData( Object callbackObject, InputStream input, int len ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates end of the MIMEBasicPart.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @see #startBasicPart
|
||||||
|
*/
|
||||||
|
public void endBasicPart(Object callbackObject) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates start of a new MIMEMultiPart.
|
||||||
|
* No reference to MIMEMultiPart object is kept internally.
|
||||||
|
* @return Object Client-supplied opaque object to be passed to subsequent callbacks.
|
||||||
|
* @see #endMultiPart
|
||||||
|
*/
|
||||||
|
public Object startMultiPart(){ return null; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that suppiles the boundary string.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @param boundary Encapsulation boundary that separates sub-body parts in a MultiPart.
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void boundary (Object callbackObject, byte[] boundary ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates end of the MultiPart.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @see #startMultiPart
|
||||||
|
*/
|
||||||
|
public void endMultiPart( Object callbackObject ){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates start of a new MIMEMessagePart.
|
||||||
|
* No reference to MIMEMessagePart object is kept internally.
|
||||||
|
* @return Object Client-supplied opaque object to be passed to subsequent callbacks.
|
||||||
|
* @see #endMessagePart
|
||||||
|
*/
|
||||||
|
public Object startMessagePart(){ return null; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that indicates end of the MessagePart.
|
||||||
|
* @param callbackObject Client-supplied opaque object.
|
||||||
|
* @see #startMessagePart
|
||||||
|
*/
|
||||||
|
public void endMessagePart( Object callbackObject ) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.InputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import netscape.messaging.mime.log;
|
||||||
|
import netscape.messaging.mime.MIMEParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The MIMEDynamicParser class defines the MIME Dynamic Parser.
|
||||||
|
* @author Carson Lee
|
||||||
|
* @version 1.0
|
||||||
|
* Dec 17,97
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @author Carson Lee
|
||||||
|
// @version %I%, %G%
|
||||||
|
public final class MIMEDynamicParser
|
||||||
|
{
|
||||||
|
protected MIMEParser p = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the Dynamic Parser.
|
||||||
|
* @param dataSink User's datasink for callbacks. Cannot be null.
|
||||||
|
* @param decodeData Whether the parser should decode message body-part data; if
|
||||||
|
* true, the parser decodes the data; if false, the parser stores or returns raw data.
|
||||||
|
* @param localStorage Whether the parser should save references to all callback data
|
||||||
|
* and build up the MIMEMessage that is available as a whole after endParse().
|
||||||
|
* If true, the parser manages data locally; if false, the does not save references to
|
||||||
|
* data supplied through callbacks.
|
||||||
|
* @return New MIMEParser object
|
||||||
|
* @exception MIMEException If dataSink is null or an error occurs.
|
||||||
|
*/
|
||||||
|
private MIMEDynamicParser( MIMEDataSink dataSink,
|
||||||
|
boolean decodeData,
|
||||||
|
boolean localStorage ) throws MIMEException
|
||||||
|
{
|
||||||
|
p = new MIMEParser( dataSink, decodeData, localStorage );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the Dynamic Parser.
|
||||||
|
* @param dataSink User's datasink for callbacks. Cannot be null.
|
||||||
|
* @return New MIMEParser object
|
||||||
|
* @exception MIMEException If dataSink is null or an error occurs.
|
||||||
|
*/
|
||||||
|
public MIMEDynamicParser (MIMEDataSink dataSink) throws MIMEException
|
||||||
|
{
|
||||||
|
p = new MIMEParser (dataSink, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a new parse cycle and resets parser internal data-structures.
|
||||||
|
* This method is called when the user wants to initiate message parsing.
|
||||||
|
* @exception MIMEException If the parser object was not properly set-up.
|
||||||
|
*/
|
||||||
|
public void beginParse() throws MIMEException
|
||||||
|
{
|
||||||
|
p.beginParse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse more incoming data.
|
||||||
|
* This method can be called several times between beginParse() and endParse().
|
||||||
|
* @param input User's input-stream. Source of data for parse operation.
|
||||||
|
* @exception MIMEException If parser detects MIME format errors.
|
||||||
|
*/
|
||||||
|
public void parse( InputStream input ) throws MIMEException
|
||||||
|
{
|
||||||
|
p.parse( input );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses more incoming data.
|
||||||
|
* This method can be called several times between beginParse() and endParse().
|
||||||
|
* @param inputData User's input. Source of data for parse operation.
|
||||||
|
* @exception MIMEException If parser detects MIME format errors.
|
||||||
|
*/
|
||||||
|
public void parse (byte [] inputData) throws MIMEException
|
||||||
|
{
|
||||||
|
parse (new ByteArrayInputStream (inputData));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends parse. Tells parser there is no more data to parse.
|
||||||
|
* Parser winds up parse operation of the message being parsed.
|
||||||
|
* @exception MIMEException If parser detects MIME format errors.
|
||||||
|
*/
|
||||||
|
public void endParse() throws MIMEException
|
||||||
|
{
|
||||||
|
p.endParse();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The MIMEException class represents an internal error in
|
||||||
|
* the MIME API implementation of the Messaging Access SDK.
|
||||||
|
* A MIMEException is thrown when the Messaging Access SDK
|
||||||
|
* detects a MIME API error condition.
|
||||||
|
* @author Prasad Yendluri
|
||||||
|
*/
|
||||||
|
public class MIMEException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MIMEException object.
|
||||||
|
* Default constructor for the MIMEException class.
|
||||||
|
*/
|
||||||
|
public MIMEException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MIMEException object given a descriptive string.
|
||||||
|
* @param s String that describes the exception.
|
||||||
|
*/
|
||||||
|
public MIMEException(String s)
|
||||||
|
{
|
||||||
|
super(s);
|
||||||
|
netscape.messaging.mime.log.errorLog(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,931 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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;
|
||||||
|
import netscape.messaging.mime.MIMEDataSink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The MIMEMessage class represents the MIME message.
|
||||||
|
* A MIME Message is made up of a set of headers and message content.
|
||||||
|
* The message content itself comprises one of the MIMEBody types:
|
||||||
|
* MIMEBasicPart, MIMEMultiPart, and MIMEMessagePart.
|
||||||
|
* @author Prasad Yendluri
|
||||||
|
*/
|
||||||
|
public class MIMEMessage implements Cloneable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* BodyPart is a MIMEBasicPart object.
|
||||||
|
*/
|
||||||
|
public static final int BASICPART = 0;
|
||||||
|
/**
|
||||||
|
* BodyPart is a MIMEMultiPart object.
|
||||||
|
*/
|
||||||
|
public static final int MULTIPART = 1;
|
||||||
|
/**
|
||||||
|
* BodyPart is a MIMEMessagePart object.
|
||||||
|
*/
|
||||||
|
public static final int MESSAGEPART = 2;
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Internal members not visible at the API
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
private static final int UNINITIALIZED = -1;
|
||||||
|
|
||||||
|
private static final byte[] CRLF = "\r\n".getBytes();
|
||||||
|
private static final byte[] LF = "\n".getBytes();
|
||||||
|
|
||||||
|
private int m_contentTransferEncoding;
|
||||||
|
protected int m_parsedPart;
|
||||||
|
private boolean m_fplaceTwo;
|
||||||
|
|
||||||
|
// The key to the hashTable below is the name of the header field.
|
||||||
|
// To make sure we handle case differences in the header-name, we
|
||||||
|
// must convert the header name to lower-case always prior to the
|
||||||
|
// hash look-up. The entries added to the hash table are objects of
|
||||||
|
// class Header.
|
||||||
|
private Hashtable m_822HeadersTable;
|
||||||
|
private Vector m_repeatHdrs;
|
||||||
|
|
||||||
|
// Body
|
||||||
|
private int m_bodyType; // one of BASICPART, MULTIPART, MESSAGEPART
|
||||||
|
private MIMEBodyPart m_theBody; // must be one of BASICPART, MULTIPART, MESSAGEPART
|
||||||
|
|
||||||
|
// callback support
|
||||||
|
MIMEParser m_parser;
|
||||||
|
MIMEDataSink m_dataSink;
|
||||||
|
private Object m_UserObject;
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// CONSTRUCTORS
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor for the MIMEMessage class.
|
||||||
|
*/
|
||||||
|
public MIMEMessage ()
|
||||||
|
{
|
||||||
|
m_822HeadersTable = new Hashtable();
|
||||||
|
|
||||||
|
m_parsedPart = 0;
|
||||||
|
m_contentTransferEncoding = UNINITIALIZED;
|
||||||
|
m_bodyType = UNINITIALIZED;
|
||||||
|
m_theBody = null;
|
||||||
|
m_parser = null;
|
||||||
|
m_dataSink = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a MIMEMessage object given a set of RFC822 headers.
|
||||||
|
* @param headers List of rfc822 headers to set in the message.
|
||||||
|
* @exception MIMEException If the headers are malformed.
|
||||||
|
*/
|
||||||
|
public MIMEMessage (Header[] headers) throws MIMEException
|
||||||
|
{
|
||||||
|
m_822HeadersTable = new Hashtable();
|
||||||
|
|
||||||
|
m_parsedPart = 0;
|
||||||
|
m_contentTransferEncoding = UNINITIALIZED;
|
||||||
|
m_bodyType = UNINITIALIZED;
|
||||||
|
m_theBody = null;
|
||||||
|
|
||||||
|
if (headers != null)
|
||||||
|
for (int i = 0, len = headers.length; i < len; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setHeader (headers[i].getName(), headers[i].getValue());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a (multi-part) MIMEMessage with given text and file.
|
||||||
|
* If filename parameter is null, builds a text message with textIS. Encoding will be E7BIT.
|
||||||
|
* If textIS parameter is null, builds a message with only the filename file as an attachment.
|
||||||
|
* If both textIS and filename parameters are null, an exception is thrown.
|
||||||
|
* @param textIS InputStream to text that becomes text part of the message. Can be null.
|
||||||
|
* @param filename Full name of file that becomes a part of the message. Can be null.
|
||||||
|
* @param encoding Encoding for the file attachment. To pick default value, pass -1.
|
||||||
|
* @see MIMEBodyPart#BASE64
|
||||||
|
* @see MIMEBodyPart#QP
|
||||||
|
* @see MIMEBodyPart#BINARY
|
||||||
|
* @see MIMEBodyPart#E7BIT
|
||||||
|
* @see MIMEBodyPart#E8BIT
|
||||||
|
* @exception MIMEException If both textIS and filename are null or encoding is invalid
|
||||||
|
* @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 MIMEMessage (InputStream textIS, String filename, int encoding) throws
|
||||||
|
MIMEException, FileNotFoundException, SecurityException, IOException
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_txtPart;
|
||||||
|
MIMEBasicPart l_filePart;
|
||||||
|
FileInputStream l_fis;
|
||||||
|
fileMIMEType l_fmt;
|
||||||
|
|
||||||
|
// Message initialization
|
||||||
|
m_822HeadersTable = new Hashtable();
|
||||||
|
m_parsedPart = 0;
|
||||||
|
m_contentTransferEncoding = UNINITIALIZED;
|
||||||
|
m_bodyType = UNINITIALIZED;
|
||||||
|
m_theBody = null;
|
||||||
|
|
||||||
|
if (textIS == null && 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);
|
||||||
|
|
||||||
|
|
||||||
|
if (textIS != null && filename != null)
|
||||||
|
{
|
||||||
|
MIMEMultiPart l_mmp = new MIMEMultiPart (textIS, filename, encoding);
|
||||||
|
this.setBody (l_mmp, false);
|
||||||
|
}
|
||||||
|
else if (textIS != null) // text-part only!
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
this.setBody (l_txtPart, false);
|
||||||
|
}
|
||||||
|
else if (filename != null) // file-part only!
|
||||||
|
{
|
||||||
|
l_fis = new FileInputStream (filename);
|
||||||
|
|
||||||
|
// 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=" + 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=" + l_fmt.file_shortname));
|
||||||
|
l_filePart.setContentDescription (l_fmt.file_shortname);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set body-data of this part
|
||||||
|
l_filePart.setBodyData (l_fis);
|
||||||
|
this.setBody (l_filePart, false);
|
||||||
|
|
||||||
|
} // filePart
|
||||||
|
|
||||||
|
} // MIMEMessage()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// All the Methods Specific to this Class
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets any RFC-822 headers including X-headers. Overwrites the existing
|
||||||
|
* value if header exists already.
|
||||||
|
* @param name Name of the header field.
|
||||||
|
* @param value Value of the header field to be added.
|
||||||
|
* @exception MIMEException If either name or value are NULL
|
||||||
|
* @see MIMEHelper#encodeHeader
|
||||||
|
*/
|
||||||
|
public void setHeader (String name, String value) throws MIMEException
|
||||||
|
{
|
||||||
|
if ((name == null) || (value == null))
|
||||||
|
throw new MIMEException ("Invalid NULL Header name or value");
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
|
||||||
|
Header l_hdr = new Header (name, value);
|
||||||
|
m_822HeadersTable.put (l_hashKey, l_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the value to an existing RFC822 header. Creates new header if
|
||||||
|
* one does not exist already.
|
||||||
|
* @param name Name of the header field.
|
||||||
|
* @param value Value of the header field to be added.
|
||||||
|
* @exception MIMEException If either name or value are NULL
|
||||||
|
* @see MIMEHelper#encodeHeader
|
||||||
|
*/
|
||||||
|
public void addHeader (String name, String value) throws MIMEException
|
||||||
|
{
|
||||||
|
if ((name == null) || (value == null))
|
||||||
|
throw new MIMEException ("Invalid NULL Header name or value");
|
||||||
|
|
||||||
|
if (m_fplaceTwo == true)
|
||||||
|
{
|
||||||
|
addHeader2 (name, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
Header l_hdr = (Header) m_822HeadersTable.get (l_hashKey);
|
||||||
|
if (l_hdr == null)
|
||||||
|
{
|
||||||
|
// Add a new one.
|
||||||
|
Header l_newhdr = new Header (name, value);
|
||||||
|
m_822HeadersTable.put (l_hashKey, l_newhdr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Append value to existing one.
|
||||||
|
StringBuffer l_oldvalue = new StringBuffer (l_hdr.getValue());
|
||||||
|
l_oldvalue.append (value);
|
||||||
|
|
||||||
|
Header l_newhdr = new Header (name, l_oldvalue.toString());
|
||||||
|
m_822HeadersTable.put (l_hashKey, l_newhdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeader2 (String name, String value) throws MIMEException
|
||||||
|
{
|
||||||
|
Header l_oldHdr, l_newhdr;
|
||||||
|
int idx = m_repeatHdrs.size() -1;
|
||||||
|
|
||||||
|
l_oldHdr = (Header) m_repeatHdrs.elementAt (idx);
|
||||||
|
|
||||||
|
if (!(l_oldHdr.m_headerName.equalsIgnoreCase (name)))
|
||||||
|
{
|
||||||
|
l_newhdr = new Header (name, value);
|
||||||
|
m_repeatHdrs.addElement (l_newhdr);
|
||||||
|
m_fplaceTwo = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_repeatHdrs.removeElementAt (idx);
|
||||||
|
|
||||||
|
StringBuffer l_oldvalue = new StringBuffer (l_oldHdr.getValue());
|
||||||
|
l_oldvalue.append (value);
|
||||||
|
|
||||||
|
l_newhdr = new Header (name, l_oldvalue.toString());
|
||||||
|
m_repeatHdrs.addElement (l_newhdr);
|
||||||
|
m_fplaceTwo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a potential repeat header to the message
|
||||||
|
protected void addRHeader (String name, String value) throws MIMEException
|
||||||
|
{
|
||||||
|
if ((name == null) || (value == null))
|
||||||
|
throw new MIMEException ("Invalid NULL Header name or value");
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
Header l_hdr = (Header) m_822HeadersTable.get (l_hashKey);
|
||||||
|
|
||||||
|
if (l_hdr == null)
|
||||||
|
{
|
||||||
|
// Add a new one.
|
||||||
|
Header l_newhdr = new Header (name, value);
|
||||||
|
m_822HeadersTable.put (l_hashKey, l_newhdr);
|
||||||
|
m_fplaceTwo = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Its a repeat header!
|
||||||
|
if (m_repeatHdrs == null)
|
||||||
|
m_repeatHdrs = new Vector();
|
||||||
|
|
||||||
|
Header l_newhdr = new Header (name, value);
|
||||||
|
m_repeatHdrs.addElement (l_newhdr);
|
||||||
|
m_fplaceTwo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the requested header. NULL if the header is not present.
|
||||||
|
* @param name Name of the header field.
|
||||||
|
* @exception MIMEException If name is NULL
|
||||||
|
* @see MIMEHelper#decodeHeader
|
||||||
|
*/
|
||||||
|
public String getHeader (String name) throws MIMEException
|
||||||
|
{
|
||||||
|
if (name == null)
|
||||||
|
throw new MIMEException ("Invalid NULL Header name");
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
Header l_hdr = (Header) m_822HeadersTable.get (l_hashKey);
|
||||||
|
|
||||||
|
if (l_hdr != null)
|
||||||
|
return (l_hdr.getValue());
|
||||||
|
else
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the requested header. Ignores if the header specified does not exist.
|
||||||
|
* @param name Name of the header field to delete.
|
||||||
|
* @exception MIMEException if name is null
|
||||||
|
*/
|
||||||
|
public void deleteHeader (String name) throws MIMEException
|
||||||
|
{
|
||||||
|
if (name == null)
|
||||||
|
throw new MIMEException ("Invalid NULL Header name");
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
m_822HeadersTable.remove (l_hashKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the RFC-822 headers in the Message as an array of Header objects.
|
||||||
|
* Content-Type is not returned by this Method, as separate methods to get
|
||||||
|
* Content primary type, sub-type and parameters exist.
|
||||||
|
* @exception MIMEException If no headers exist.
|
||||||
|
* @see MIMEHelper#decodeHeader
|
||||||
|
* @see getContentType
|
||||||
|
* @see getContentSubType
|
||||||
|
* @see getContentTypeParams
|
||||||
|
*/
|
||||||
|
public Header[] getAllHeaders () throws MIMEException
|
||||||
|
{
|
||||||
|
int l_numElements = m_822HeadersTable.size();
|
||||||
|
int i = 0, l_repeats = 0;
|
||||||
|
Header[] hdrs = null;
|
||||||
|
|
||||||
|
if (l_numElements <= 0)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
if (m_repeatHdrs != null)
|
||||||
|
l_repeats = m_repeatHdrs.size();
|
||||||
|
|
||||||
|
hdrs = new Header[l_numElements + l_repeats];
|
||||||
|
Enumeration he = m_822HeadersTable.elements();
|
||||||
|
|
||||||
|
while (he.hasMoreElements())
|
||||||
|
{
|
||||||
|
hdrs[i++] = (Header) he.nextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < l_repeats; j++)
|
||||||
|
hdrs[i++] = (Header) m_repeatHdrs.elementAt (j);
|
||||||
|
|
||||||
|
return (hdrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of the body of the Message.
|
||||||
|
* @exception MIMEException If no Body exists for the message.
|
||||||
|
* @see MIMEMessage#BASICPART
|
||||||
|
* @see MIMEMessage#MULTIPART
|
||||||
|
* @see MIMEMessage#MESSAGEPART
|
||||||
|
*/
|
||||||
|
public int getBodyType () throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_bodyType != UNINITIALIZED)
|
||||||
|
return (m_bodyType);
|
||||||
|
else
|
||||||
|
throw new MIMEException ("getBodyType(): No body present!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content-type of the Message.
|
||||||
|
* The content-type returned is the MIME content-type.
|
||||||
|
* @exception MIMEException If no Body exists.
|
||||||
|
*/
|
||||||
|
public String getContentType () throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_theBody == null)
|
||||||
|
throw new MIMEException ("getContentType(): No body present!");
|
||||||
|
|
||||||
|
return (m_theBody.getContentType());
|
||||||
|
|
||||||
|
|
||||||
|
/* if (m_theBody instanceof MIMEBasicPart)
|
||||||
|
* {
|
||||||
|
* MIMEBasicPart l_body = (MIMEBasicPart) m_theBody;
|
||||||
|
* return (l_body.getContentType());
|
||||||
|
* }
|
||||||
|
* else if (m_theBody instanceof MIMEMessagePart)
|
||||||
|
* {
|
||||||
|
* MIMEMessagePart l_body = (MIMEMessagePart) m_theBody;
|
||||||
|
* return (l_body.getContentType());
|
||||||
|
* }
|
||||||
|
* else if (m_theBody instanceof MIMEMultiPart)
|
||||||
|
* {
|
||||||
|
* MIMEMultiPart l_body = (MIMEMultiPart) m_theBody;
|
||||||
|
* return (l_body.getContentType());
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* throw new MIMEException ("getContentType(): Invalid body!");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content subtype of the Message. NULL if none exists.
|
||||||
|
* @exception MIMEException If no Body exists.
|
||||||
|
*/
|
||||||
|
public String getContentSubType () throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_theBody == null)
|
||||||
|
throw new MIMEException ("getContentSubType(): No body present!");
|
||||||
|
|
||||||
|
return (m_theBody.getContentSubType());
|
||||||
|
|
||||||
|
/* MIMEBodyPart l_body = (MIMEBodyPart) m_theBody;
|
||||||
|
* return (l_body.getContentSubType());
|
||||||
|
*
|
||||||
|
* if (m_theBody instanceof MIMEBasicPart)
|
||||||
|
* {
|
||||||
|
* MIMEBasicPart l_body = (MIMEBasicPart) m_theBody;
|
||||||
|
* return (l_body.getContentSubType());
|
||||||
|
* }
|
||||||
|
* else if (m_theBody instanceof MIMEMessagePart)
|
||||||
|
* {
|
||||||
|
* MIMEMessagePart l_body = (MIMEMessagePart) m_theBody;
|
||||||
|
* return (l_body.getContentSubType());
|
||||||
|
* }
|
||||||
|
* else if (m_theBody instanceof MIMEMultiPart)
|
||||||
|
* {
|
||||||
|
* MIMEMultiPart l_body = (MIMEMultiPart) m_theBody;
|
||||||
|
* return (l_body.getContentSubType());
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* throw new MIMEException ("getContentSubType(): Invalid body!");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content-type params of the Message. NULL if none exist.
|
||||||
|
* @exception MIMEException If no Body exists.
|
||||||
|
*/
|
||||||
|
public String getContentTypeParams () throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_theBody == null)
|
||||||
|
throw new MIMEException ("getContentTypeParams(): No body present!");
|
||||||
|
|
||||||
|
return (m_theBody.getContentTypeParams());
|
||||||
|
|
||||||
|
/* MIMEBodyPart l_body = (MIMEBodyPart) m_theBody;
|
||||||
|
* return (l_body.getContentTypeParams());
|
||||||
|
*
|
||||||
|
* if (m_theBody instanceof MIMEBasicPart)
|
||||||
|
* {
|
||||||
|
* MIMEBasicPart l_body = (MIMEBasicPart) m_theBody;
|
||||||
|
* return (l_body.getContentTypeParams());
|
||||||
|
* }
|
||||||
|
* else if (m_theBody instanceof MIMEMessagePart)
|
||||||
|
* {
|
||||||
|
* MIMEMessagePart l_body = (MIMEMessagePart) m_theBody;
|
||||||
|
* return (l_body.getContentTypeParams());
|
||||||
|
* }
|
||||||
|
* else if (m_theBody instanceof MIMEMultiPart)
|
||||||
|
* {
|
||||||
|
* MIMEMultiPart l_body = (MIMEMultiPart) m_theBody;
|
||||||
|
* return (l_body.getContentTypeParams());
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* throw new MIMEException ("getContentTypeParams(): Invalid body!");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an Object of corresponding MIMEBodyPart type that is
|
||||||
|
* the body of this Message.
|
||||||
|
* @param clone Whether to return a reference to the internal object or a cloned copy;
|
||||||
|
* if true: cloned copy; if false: reference to the object.
|
||||||
|
* @exception MIMEException If no Body exists.
|
||||||
|
* @see MIMEBasicPart
|
||||||
|
* @see MIMEMultiPart
|
||||||
|
* @see MIMEMessagePart
|
||||||
|
*/
|
||||||
|
public Object getBody (boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_theBody == null)
|
||||||
|
throw new MIMEException ("getBody(): No body present!");
|
||||||
|
|
||||||
|
if (m_theBody instanceof MIMEBasicPart)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_body = (MIMEBasicPart) m_theBody;
|
||||||
|
return ( clone ? l_body.clone() : l_body );
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_theBody instanceof MIMEMessagePart)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_body = (MIMEMessagePart) m_theBody;
|
||||||
|
return ( clone ? l_body.clone() : l_body );
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_theBody instanceof MIMEMultiPart)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEMultiPart l_body = (MIMEMultiPart) m_theBody;
|
||||||
|
return ( clone ? l_body.clone() : l_body );
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new MIMEException ("getBody(): Invalid body!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an Object of corresponding MIME BodyPart type that is
|
||||||
|
* the body of this Message.
|
||||||
|
* @exception MIMEException If no Body exists.
|
||||||
|
*/
|
||||||
|
protected Object getBody () throws MIMEException
|
||||||
|
{
|
||||||
|
return getBody( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the body of the Message. Has no effect if no body is present.
|
||||||
|
*/
|
||||||
|
public void deleteBody ()
|
||||||
|
{
|
||||||
|
if (m_theBody != null)
|
||||||
|
{
|
||||||
|
m_theBody = null;
|
||||||
|
m_bodyType = UNINITIALIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEBasicPart as Body of this Message. This part must already be
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message based on the
|
||||||
|
* type of the part added by this method.
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @exception MIMEException If body is already set (or) part is null.
|
||||||
|
* @see MIMEBasicPart
|
||||||
|
*/
|
||||||
|
protected void setBody (MIMEBasicPart part ) throws MIMEException
|
||||||
|
{
|
||||||
|
setBody( part, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEBodyPart as Body of this Message. This part must already be
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message based on the
|
||||||
|
* type of the part being added. This MIMEBodyPart must be an object of one of the
|
||||||
|
* three concrete classes: MIMEBasicPart, MIMEMultiPart and MIMEMessagePart.
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @param clone Whether to store a reference to the object or a cloned copy;
|
||||||
|
* if true: clones a copy; if false: stores a reference to the object.
|
||||||
|
* @exception MIMEException If body is already set, or if part is null, or
|
||||||
|
* if part is not an object of one of the three concrete classes:
|
||||||
|
* MIMEBasicPart, MIMEMultiPart, or MIMEMessagePart.
|
||||||
|
* @see MIMEBasicPart
|
||||||
|
* @see MIMEMultiPart
|
||||||
|
* @see MIMEMessagePart
|
||||||
|
*/
|
||||||
|
public void setBody (MIMEBodyPart part, boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
if (part == null)
|
||||||
|
throw new MIMEException ("setBody(): null part passed!");
|
||||||
|
|
||||||
|
if (part instanceof MIMEBasicPart)
|
||||||
|
setBody ((MIMEBasicPart) part, clone);
|
||||||
|
else if (part instanceof MIMEMessagePart)
|
||||||
|
setBody ((MIMEMessagePart) part, clone);
|
||||||
|
else if (part instanceof MIMEMultiPart)
|
||||||
|
setBody ((MIMEMultiPart) part, clone);
|
||||||
|
else
|
||||||
|
throw new MIMEException ("setBody(): Invalid part ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEBasicPart as Body of this Message. This part must already be
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message based on the
|
||||||
|
* type of the part being added.
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @param clone If false stores reference to passed object instead of cloning a copy.
|
||||||
|
* @exception MIMEException If body is already set (or) part is null.
|
||||||
|
* @see MIMEBasicPart
|
||||||
|
*/
|
||||||
|
protected void setBody (MIMEBasicPart part, boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_part = null;
|
||||||
|
|
||||||
|
if (m_theBody != null)
|
||||||
|
throw new MIMEException ("setBody(): Body already set!");
|
||||||
|
|
||||||
|
if (part == null)
|
||||||
|
throw new MIMEException ("setBody(): null part passed!");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_part = (MIMEBasicPart) ( clone ? part.clone() : part );
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_theBody = l_part;
|
||||||
|
m_bodyType = BASICPART;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEMultiPart as Body of this Message. This part must already be
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message based on the
|
||||||
|
* type of the part being added
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @exception MIMEException If body is already set (or) part is null.
|
||||||
|
* @see MIMEBasicPart
|
||||||
|
*/
|
||||||
|
protected void setBody (MIMEMultiPart part) throws MIMEException
|
||||||
|
{
|
||||||
|
setBody( part, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEMultiPart as Body of this Message. This part should have been
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message accordingly.
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @param clone If false stores reference to passed object instead of cloning a copy.
|
||||||
|
* @exception MIMEException If body is already set (or) part is null.
|
||||||
|
* @see MIMEMultiPart
|
||||||
|
*/
|
||||||
|
protected void setBody (MIMEMultiPart part, boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
MIMEMultiPart l_part = null;
|
||||||
|
|
||||||
|
if (m_theBody != null)
|
||||||
|
throw new MIMEException ("setBody(): Body already set!");
|
||||||
|
|
||||||
|
if (part == null)
|
||||||
|
throw new MIMEException ("setBody(): null part passed!");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_part = (MIMEMultiPart) ( clone ? part.clone() : part );
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_theBody = l_part;
|
||||||
|
m_bodyType = MULTIPART;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEMessagePart as Body of this Message. This part must already be
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message based on the
|
||||||
|
* type of the part being added.
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @exception MIMEException If body is already set (or) part is null.
|
||||||
|
* @see MIMEBasicPart
|
||||||
|
*/
|
||||||
|
protected void setBody (MIMEMessagePart part) throws MIMEException
|
||||||
|
{
|
||||||
|
setBody( part, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MIMEMessagePart as Body of this Message. This part must already be
|
||||||
|
* constructed and fully set-up. Sets the content-type of the message accordingly.
|
||||||
|
* @param part BodyPart to add.
|
||||||
|
* @param clone If false stores reference to passed object instead of cloning a copy.
|
||||||
|
* @exception MIMEException If body is already set (or) part is null.
|
||||||
|
* @see MIMEMessagePart
|
||||||
|
*/
|
||||||
|
protected void setBody (MIMEMessagePart part, boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_part = null;
|
||||||
|
|
||||||
|
if (m_theBody != null)
|
||||||
|
throw new MIMEException ("setBody(): Body already set!");
|
||||||
|
|
||||||
|
if (part == null)
|
||||||
|
throw new MIMEException ("setBody(): null part passed!");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_part = (MIMEMessagePart) ( clone ? part.clone() : part );
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_theBody = l_part;
|
||||||
|
m_bodyType = MESSAGEPART;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs a byte-stream for this Message in MIME format with transfer encoding
|
||||||
|
* applied to all bodyParts as applicable.
|
||||||
|
* @param fullfilename Filename, including full path to write the byte-stream to.
|
||||||
|
* @exception IOException If an IO error occurs.
|
||||||
|
* @exception MIMEException If any required fields in the bodyPart are not set-up.
|
||||||
|
*/
|
||||||
|
public void putByteStream (String fullfilename) throws IOException, MIMEException
|
||||||
|
{
|
||||||
|
FileOutputStream fos;
|
||||||
|
fos = new FileOutputStream (fullfilename);
|
||||||
|
putByteStream (fos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs a byte stream for this Message in MIME format with transfer encoding
|
||||||
|
* applied to all bodyParts as applicable.
|
||||||
|
* @param os OutputStream to write to.
|
||||||
|
* @exception IOException If an IO error occurs.
|
||||||
|
* @exception MIMEException If detects an error during encoding.
|
||||||
|
*/
|
||||||
|
public void putByteStream (OutputStream os) throws IOException, MIMEException
|
||||||
|
{
|
||||||
|
// Don't write content-type here. The Body will do that. That is, if it were
|
||||||
|
// a multi-part, it would do that. If it were a basic-part, it would do that etc.
|
||||||
|
|
||||||
|
if (m_theBody == null)
|
||||||
|
{
|
||||||
|
throw new MIMEException ("MIMEMessage.putByteStream(). No body!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// write out all the headers.
|
||||||
|
//StringBuffer l_hdrbuf;
|
||||||
|
boolean l_fMIMEVersionWritten = false;
|
||||||
|
byte[] l_bytebuf;
|
||||||
|
|
||||||
|
Header[] hdrs = getAllHeaders ();
|
||||||
|
|
||||||
|
if (hdrs != null)
|
||||||
|
for (int i = 0, len = hdrs.length; i < len; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//l_bytebuf = l_hdrbuf.toString().getBytes("iso-8859-1");
|
||||||
|
if (l_fMIMEVersionWritten == false &&
|
||||||
|
(hdrs[i].m_headerName).equalsIgnoreCase("MIME-Version"))
|
||||||
|
l_fMIMEVersionWritten = true;
|
||||||
|
l_bytebuf = MIMEHelper.unicodeToASCII (hdrs[i].getLine());
|
||||||
|
os.write (l_bytebuf);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (hdrs[i].getLine() + "> " + e.getMessage());
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
|
||||||
|
// Now put the MIME Version.
|
||||||
|
if (!l_fMIMEVersionWritten && m_parsedPart==0)
|
||||||
|
{
|
||||||
|
l_bytebuf = MIMEHelper.unicodeToASCII ("MIME-Version: 1.0\r\n");
|
||||||
|
os.write (l_bytebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// call thebody.putByteStream()
|
||||||
|
if (m_theBody instanceof MIMEBasicPart)
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_body = (MIMEBasicPart) m_theBody;
|
||||||
|
l_body.putByteStream(os);
|
||||||
|
}
|
||||||
|
else if (m_theBody instanceof MIMEMessagePart)
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_body = (MIMEMessagePart) m_theBody;
|
||||||
|
l_body.putByteStream(os);
|
||||||
|
}
|
||||||
|
else if (m_theBody instanceof MIMEMultiPart)
|
||||||
|
{
|
||||||
|
MIMEMultiPart l_body = (MIMEMultiPart) m_theBody;
|
||||||
|
l_body.putByteStream(os, true); // needPreamble!
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new MIMEException ("putByteStream(): Invalid body!");
|
||||||
|
|
||||||
|
//os.write (CRLF); // terminate the message
|
||||||
|
|
||||||
|
} // end putByteStream()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones an instance of this MIMEMessage object.
|
||||||
|
* @exception CloneNotSupportedException If thrown by constituent components.
|
||||||
|
*/
|
||||||
|
public Object clone () throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
MIMEMessage l_theClone = (MIMEMessage) super.clone();
|
||||||
|
|
||||||
|
if (m_822HeadersTable != null)
|
||||||
|
l_theClone.m_822HeadersTable = (Hashtable) m_822HeadersTable.clone();
|
||||||
|
|
||||||
|
if (m_repeatHdrs != null)
|
||||||
|
l_theClone.m_repeatHdrs = (Vector) m_repeatHdrs.clone();
|
||||||
|
|
||||||
|
if (m_theBody != null)
|
||||||
|
{
|
||||||
|
if (m_theBody instanceof MIMEBasicPart)
|
||||||
|
{
|
||||||
|
MIMEBasicPart l_body = (MIMEBasicPart) m_theBody;
|
||||||
|
l_theClone.m_theBody = (MIMEBasicPart) l_body.clone();
|
||||||
|
}
|
||||||
|
else if (m_theBody instanceof MIMEMessagePart)
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_body = (MIMEMessagePart) m_theBody;
|
||||||
|
l_theClone.m_theBody = (MIMEMessagePart) l_body.clone();
|
||||||
|
}
|
||||||
|
else if (m_theBody instanceof MIMEMultiPart)
|
||||||
|
{
|
||||||
|
MIMEMultiPart l_body = (MIMEMultiPart) m_theBody;
|
||||||
|
l_theClone.m_theBody = (MIMEMultiPart) l_body.clone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
l_theClone.m_UserObject = m_UserObject;
|
||||||
|
|
||||||
|
} // end if
|
||||||
|
|
||||||
|
return (l_theClone);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getUserObject() { return m_UserObject; }
|
||||||
|
protected void setUserObject( Object userObject ) { m_UserObject = userObject; }
|
||||||
|
}
|
|
@ -0,0 +1,659 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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 MIMEMessagePart class implements the MIME MessagePart Content Type.
|
||||||
|
* @author Prasad Yendluri
|
||||||
|
*/
|
||||||
|
public class MIMEMessagePart extends MIMEBodyPart implements Cloneable
|
||||||
|
{
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Internal members not visible at the API
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
// Encodings
|
||||||
|
private static final int BINARY = MIMEBodyPart.BINARY;
|
||||||
|
private static final int E7BIT = MIMEBodyPart.E7BIT;
|
||||||
|
private static final int E8BIT = MIMEBodyPart.E8BIT;
|
||||||
|
|
||||||
|
|
||||||
|
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 MESSAGE = "Message";
|
||||||
|
|
||||||
|
private int m_contentTransferEncoding;
|
||||||
|
private int m_parsedPart;
|
||||||
|
|
||||||
|
// The key to the hashTable below is the name of the header field.
|
||||||
|
// To make sure we handle case differences in the header-name, we
|
||||||
|
// must convert the header name to lower-case always prior to the
|
||||||
|
// hash look-up. The entries added to the hash table are objects of
|
||||||
|
// class Header.
|
||||||
|
private Hashtable m_ExtBodyHeadersTable;
|
||||||
|
|
||||||
|
private MIMEMessage m_theMessage;
|
||||||
|
private InputStream m_partial;
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// CONSTRUCTORS
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a MIMEMessagePart object.
|
||||||
|
* Default constructor for the MIMEMessagePart.
|
||||||
|
*/
|
||||||
|
public MIMEMessagePart ()
|
||||||
|
{
|
||||||
|
m_parsedPart = 0;
|
||||||
|
m_UserObject = null;
|
||||||
|
m_contentDisposition = UNINITIALIZED;
|
||||||
|
m_contentTransferEncoding = UNINITIALIZED;
|
||||||
|
m_theMessage = null;
|
||||||
|
m_partial = null;
|
||||||
|
m_ExtBodyHeadersTable = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a MIMEMessagePart object from the given MIMEMessage Object.
|
||||||
|
* @param msg The message that should form the body of this part.
|
||||||
|
* @exception MIMEException If msg is null.
|
||||||
|
*/
|
||||||
|
public MIMEMessagePart (MIMEMessage msg) throws MIMEException
|
||||||
|
{
|
||||||
|
m_parsedPart = 0;
|
||||||
|
m_contentDisposition = UNINITIALIZED;
|
||||||
|
m_contentTransferEncoding = UNINITIALIZED;
|
||||||
|
|
||||||
|
if (msg != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_theMessage = (MIMEMessage) msg.clone();
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new MIMEException ("MIMEMessagePart(): null message passed." );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Methods from Interface MIMEBodyPart
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Content-Type of this MIME Part. Always returns the string "Message".
|
||||||
|
*/
|
||||||
|
public String getContentType ()
|
||||||
|
{
|
||||||
|
return (MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Content-Transfer-Encoding of this MIME Part.
|
||||||
|
* Only BINARY, E7BIT, and E8BIT are applicable to MIMEMessagePart.
|
||||||
|
* Additionally, for message/partial and message/external-body, the MIME
|
||||||
|
* standard requires E7BIT encoding. It is possible to
|
||||||
|
* set encoding prior to setting the contentSubType.
|
||||||
|
* If a different value is specified, no error occurs; instead,
|
||||||
|
* this method will be overridden by the putByteStream() method.
|
||||||
|
* @param encoding Value that represents the encoding.
|
||||||
|
* @see MIMEBodyPart#BINARY
|
||||||
|
* @see MIMEBodyPart#E7BIT
|
||||||
|
* @see MIMEBodyPart#E8BIT
|
||||||
|
* @exception MIMEException If the value is not one of BINARY, E7BIT or E8BIT
|
||||||
|
*/
|
||||||
|
public void setContentEncoding (int encoding) throws MIMEException
|
||||||
|
{
|
||||||
|
switch (encoding)
|
||||||
|
{
|
||||||
|
case BINARY:
|
||||||
|
case E7BIT:
|
||||||
|
case E8BIT:
|
||||||
|
m_contentTransferEncoding = encoding;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new MIMEException ("Invalid/Inapplicable Content-Transfer-Encoding: " + encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns value of Content-Transfer-Encoding of this MIME Part. -1 if none present.
|
||||||
|
* @see MIMEBodyPart#BINARY
|
||||||
|
* @see MIMEBodyPart#E7BIT
|
||||||
|
* @see MIMEBodyPart#E8BIT
|
||||||
|
*/
|
||||||
|
public int getContentEncoding ()
|
||||||
|
{
|
||||||
|
if (m_contentTransferEncoding == UNINITIALIZED)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (m_contentTransferEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Methods Specific to this Class alone.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified message as the body of this part.
|
||||||
|
* @param msg Message to be set as body of this part.
|
||||||
|
* @exception MIMEException If already set (or) can not be set.
|
||||||
|
*/
|
||||||
|
protected void setMessage (MIMEMessage msg) throws MIMEException
|
||||||
|
{
|
||||||
|
setMessage (msg, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified message as the body of this part.
|
||||||
|
* @param msg Message to be set as body of this part.
|
||||||
|
* @param clone If false stores reference to passed object instead of cloning a copy.
|
||||||
|
* @exception MIMEException If already set (or) can not be set.
|
||||||
|
*/
|
||||||
|
public void setMessage (MIMEMessage msg, boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_theMessage != null)
|
||||||
|
throw new MIMEException ("setMessage(): already set!");
|
||||||
|
|
||||||
|
if (msg != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_theMessage = (MIMEMessage) (clone ? msg.clone() : msg);
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new MIMEException ("setMessage(): null message passed." );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the MIMEMessage that is the Body of this part.
|
||||||
|
* @exception MIMEException If no Message exists in body-data.
|
||||||
|
*/
|
||||||
|
protected MIMEMessage getMessage () throws MIMEException
|
||||||
|
{
|
||||||
|
return getMessage (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the MIMEMessage that is the Body of this part.
|
||||||
|
* @param clone If false returns reference to the object instead of a cloned copy.
|
||||||
|
* @exception MIMEException If no Message exists in body-data.
|
||||||
|
*/
|
||||||
|
public MIMEMessage getMessage (boolean clone) throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_theMessage == null)
|
||||||
|
throw new MIMEException ("getMessage(): null Message in body!");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEMessage l_msg = (MIMEMessage) (clone ? m_theMessage.clone() : m_theMessage);
|
||||||
|
return (l_msg);
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the MIMEMessage that is the Body of this part.
|
||||||
|
* Noop if no body was ever set.
|
||||||
|
*/
|
||||||
|
public void deleteMessage ()
|
||||||
|
{
|
||||||
|
m_theMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the headers associated with External Body, for external-body content-subtypes
|
||||||
|
* only. If already set, these headers are
|
||||||
|
* ignored for other subtypes (rfc822 and message-partial).
|
||||||
|
* @param name Name of the header field. Should not include ':'
|
||||||
|
* @param value Value of the header field to be added.
|
||||||
|
* @exception MIMEException if either of name or value is null
|
||||||
|
*/
|
||||||
|
public void setExtBodyHeader (String name, String value) throws MIMEException
|
||||||
|
{
|
||||||
|
if ((name == null) || (value == null))
|
||||||
|
throw new MIMEException ("Invalid NULL Header name or value");
|
||||||
|
|
||||||
|
if ( name.indexOf (':') > -1)
|
||||||
|
throw new MIMEException ("Invalid ':' in Header name");
|
||||||
|
|
||||||
|
if (m_ExtBodyHeadersTable == null)
|
||||||
|
m_ExtBodyHeadersTable = new Hashtable();
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
Header l_hdr = new Header (name, value);
|
||||||
|
m_ExtBodyHeadersTable.put (l_hashKey, l_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the specified header associated with External Body.
|
||||||
|
* Applicable to external-body subtypes only.
|
||||||
|
* Returns NULL if the header is not present.
|
||||||
|
* @param name Name of the header field.
|
||||||
|
* @exception MIMEException If name passed is a NULL.
|
||||||
|
*/
|
||||||
|
public String getExtBodyHeader (String name) throws MIMEException
|
||||||
|
{
|
||||||
|
if (name == null)
|
||||||
|
throw new MIMEException ("Invalid NULL Header name");
|
||||||
|
|
||||||
|
if (m_ExtBodyHeadersTable == null)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
String l_hashKey = name.toLowerCase(); // Keys are always lower case
|
||||||
|
Header l_hdr = (Header) m_ExtBodyHeadersTable.get (l_hashKey);
|
||||||
|
|
||||||
|
if (l_hdr != null)
|
||||||
|
return (l_hdr.getValue()); // getValue() returns a new string.
|
||||||
|
else
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the headers in this Part as an array of Header objects.
|
||||||
|
* @exception MIMEException If no headers exist.
|
||||||
|
*/
|
||||||
|
public Header[] getAllHeaders () throws MIMEException
|
||||||
|
{
|
||||||
|
int l_numElements = 0, i = 0;
|
||||||
|
|
||||||
|
if (m_ExtBodyHeadersTable != null)
|
||||||
|
l_numElements = m_ExtBodyHeadersTable.size();
|
||||||
|
|
||||||
|
if (l_numElements <= 0)
|
||||||
|
return (null);
|
||||||
|
|
||||||
|
Header[] hdrs = new Header [l_numElements];
|
||||||
|
Enumeration he = m_ExtBodyHeadersTable.elements();
|
||||||
|
|
||||||
|
while (he.hasMoreElements())
|
||||||
|
{
|
||||||
|
hdrs[i++] = (Header) he.nextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hdrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the message partial. Stores reference to the supplied inputStream.
|
||||||
|
* Does not copy data. The data in partial is copied as is by putByteStream().
|
||||||
|
* To be used with message/partial subtypes only. It is an error to setPartial()
|
||||||
|
* for other subtypes (rfc822 and external-body).
|
||||||
|
* @param instream inputStream that supplies the data for this partial.
|
||||||
|
* @exception MIMEException if content-subtype is not partial or if already set.
|
||||||
|
* @see deletePartial
|
||||||
|
*/
|
||||||
|
protected void setPartial (InputStream instream) throws MIMEException
|
||||||
|
{
|
||||||
|
if (m_partial != null)
|
||||||
|
throw new MIMEException ("Partial already set.");
|
||||||
|
|
||||||
|
if ((m_contentSubType != null) &&
|
||||||
|
(!m_contentSubType.equalsIgnoreCase("partial")))
|
||||||
|
throw new MIMEException ("Content-Subtype partial expected.");
|
||||||
|
|
||||||
|
m_partial = instream;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the message partial data of this part. Ignores if partial was not set.
|
||||||
|
* @see setPartial
|
||||||
|
*/
|
||||||
|
protected void deletePartial ()
|
||||||
|
{
|
||||||
|
m_partial = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs a byte-stream for this part with its MIME part headers and encoded
|
||||||
|
* body data.
|
||||||
|
* @param os OutputStream to write to.
|
||||||
|
* @exception IOException If an IO error occurs.
|
||||||
|
* @exception MIMEException If encoding error is detected.
|
||||||
|
*/
|
||||||
|
public void putByteStream (OutputStream os) throws IOException, MIMEException
|
||||||
|
{
|
||||||
|
boolean l_external_body = false;
|
||||||
|
boolean l_message_partial = false;
|
||||||
|
String l_contentSubType = null;
|
||||||
|
if (m_contentSubType != null)
|
||||||
|
l_contentSubType = m_contentSubType.trim();
|
||||||
|
|
||||||
|
if ((l_contentSubType != null) &&
|
||||||
|
(l_contentSubType.equalsIgnoreCase("external-body")))
|
||||||
|
{
|
||||||
|
l_external_body = true;
|
||||||
|
|
||||||
|
if (m_ExtBodyHeadersTable == null);
|
||||||
|
//throw new MIMEException ("External body header Content-Id required for external-body");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((l_contentSubType != null) &&
|
||||||
|
(l_contentSubType.equalsIgnoreCase("partial")))
|
||||||
|
{
|
||||||
|
l_message_partial = true;
|
||||||
|
|
||||||
|
if (m_partial == null)
|
||||||
|
throw new MIMEException ("Message partial not set");
|
||||||
|
|
||||||
|
if (m_contentTransferEncoding != E7BIT && m_contentTransferEncoding != UNINITIALIZED)
|
||||||
|
throw new MIMEException ("Bad content-encoding for message/partial");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_theMessage == null) && (!l_external_body) && (!l_message_partial))
|
||||||
|
{
|
||||||
|
throw new MIMEException ("putByteStream(): null Message body!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out the headers first
|
||||||
|
StringBuffer l_hdrbuf = new StringBuffer (HDRBUFSZ);
|
||||||
|
byte[] l_bytebuf;
|
||||||
|
|
||||||
|
// content-type
|
||||||
|
l_hdrbuf.append ("Content-Type: message/");
|
||||||
|
|
||||||
|
if (m_contentSubType != null)
|
||||||
|
l_hdrbuf.append (m_contentSubType);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_theMessage != null)
|
||||||
|
l_hdrbuf.append ("rfc822"); // default
|
||||||
|
else
|
||||||
|
throw new MIMEException ("putByteStream(): No content-subtype." );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_contentTypeParams != null && m_contentTypeParams.length() > 0)
|
||||||
|
{
|
||||||
|
l_hdrbuf.append ("; ");
|
||||||
|
l_hdrbuf.append (m_contentTypeParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
l_hdrbuf.append ("\r\n");
|
||||||
|
|
||||||
|
// write the header out 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content-transfer-encoding
|
||||||
|
//if (m_contentTransferEncoding == UNINITIALIZED)
|
||||||
|
//{
|
||||||
|
// m_contentTransferEncoding = E7BIT; // default
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (m_contentSubType != null)
|
||||||
|
{
|
||||||
|
if ((l_message_partial || l_external_body) && m_contentTransferEncoding != UNINITIALIZED)
|
||||||
|
m_contentTransferEncoding = E7BIT; // As mandated by MIME standard
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!l_external_body) // for external-body we write it later
|
||||||
|
{
|
||||||
|
if (m_contentTransferEncoding != UNINITIALIZED)
|
||||||
|
{
|
||||||
|
if (l_external_body)
|
||||||
|
m_contentTransferEncoding = E7BIT;
|
||||||
|
|
||||||
|
l_hdrbuf.setLength (0);
|
||||||
|
l_hdrbuf.append ("Content-Transfer-Encoding: " +
|
||||||
|
m_stringEncoding [m_contentTransferEncoding]);
|
||||||
|
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-Transfer-Encoding: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// blank-line after headers
|
||||||
|
//l_bytebuf = new String("\r\n").getBytes("iso-8859-1");
|
||||||
|
os.write (CRLF);
|
||||||
|
|
||||||
|
// write out the message part if it is not external-body
|
||||||
|
if ((m_theMessage != null) && (!l_external_body) && (!l_message_partial))
|
||||||
|
m_theMessage.putByteStream(os);
|
||||||
|
else if (l_external_body)
|
||||||
|
{
|
||||||
|
//os.write (CRLF); // Prior to the headers for the external-body
|
||||||
|
|
||||||
|
if (m_ExtBodyHeadersTable != null)
|
||||||
|
{
|
||||||
|
Enumeration he = m_ExtBodyHeadersTable.elements();
|
||||||
|
|
||||||
|
while (he.hasMoreElements())
|
||||||
|
{
|
||||||
|
Header l_tmphdr = (Header) he.nextElement();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
l_bytebuf = MIMEHelper.unicodeToASCII (l_tmphdr.getLine());
|
||||||
|
os.write (l_bytebuf);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new MIMEException (l_tmphdr.getLine() + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // while
|
||||||
|
|
||||||
|
//if (m_contentTransferEncoding != UNINITIALIZED)
|
||||||
|
//{
|
||||||
|
// // write out content-encoding
|
||||||
|
// l_hdrbuf.setLength (0);
|
||||||
|
// l_hdrbuf.append ("Content-Transfer-Encoding: " +
|
||||||
|
// m_stringEncoding [m_contentTransferEncoding]);
|
||||||
|
// 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-Transfer-Encoding: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
os.write (CRLF); // After the headers for the external-body
|
||||||
|
|
||||||
|
} // if m_ExtBodyHeadersTable
|
||||||
|
|
||||||
|
} // if l_external_body
|
||||||
|
else if (l_message_partial)
|
||||||
|
{
|
||||||
|
os.write (CRLF);
|
||||||
|
byte l_buf [] = new byte [DATABUFSZ];
|
||||||
|
int l_len;
|
||||||
|
|
||||||
|
while ( (l_len = m_partial.read (l_buf, 0, DATABUFSZ)) > 0)
|
||||||
|
{
|
||||||
|
os.write (l_buf, 0, l_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if l_external_body
|
||||||
|
|
||||||
|
os.write (CRLF); // terminate the part
|
||||||
|
|
||||||
|
} // end putByteStream()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones an instance of this MIMEMessagePart object.
|
||||||
|
* @exception CloneNotSupportedException If thrown by a constituent components.
|
||||||
|
*/
|
||||||
|
public Object clone () throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
MIMEMessagePart l_theClone = (MIMEMessagePart) super.clone();
|
||||||
|
|
||||||
|
if (m_theMessage != null)
|
||||||
|
{
|
||||||
|
l_theClone.m_theMessage = (MIMEMessage) m_theMessage.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;
|
||||||
|
|
||||||
|
l_theClone.m_UserObject = m_UserObject;
|
||||||
|
|
||||||
|
return (l_theClone);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,911 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,73 @@
|
||||||
|
##########################################################################
|
||||||
|
# MIME makefile.
|
||||||
|
# created 9/26/97 -- Prasad
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
# environment
|
||||||
|
#SHELL = /usr/bin/ksh
|
||||||
|
|
||||||
|
# commands
|
||||||
|
JAVAC = javac
|
||||||
|
ARCH = $(shell uname -s)
|
||||||
|
|
||||||
|
ifeq ($(ARCH), SunOS)
|
||||||
|
ARCH = SOLARIS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ARCH), HP-UX)
|
||||||
|
ARCH = HPUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
# java flags
|
||||||
|
DEBUGJAVAFLAG =
|
||||||
|
OPTJAVAFLAG = -d $(CLASSDIR)
|
||||||
|
JAVAFLAGS = $(OTHERJAVAFLAGS) $(OPTJAVAFLAG) $(DEBUGJAVAFLAG)
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
# files and directories
|
||||||
|
#CLASSDIR = ./built
|
||||||
|
CLASSDIR = ../../../built/$(ARCH)/protocol
|
||||||
|
|
||||||
|
#CLASSPATH = .:$(CLASSDIR):$(JDKCLASSPATH)
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
Header.java \
|
||||||
|
fileMIMEType.java \
|
||||||
|
MIMEHelper.java \
|
||||||
|
MIMEException.java \
|
||||||
|
MIMEBodyPart.java \
|
||||||
|
MIMEBasicPart.java \
|
||||||
|
MIMEMessage.java \
|
||||||
|
MIMEMessagePart.java \
|
||||||
|
MIMEMultiPart.java \
|
||||||
|
MIMEDataSink.java \
|
||||||
|
MIMEParser.java
|
||||||
|
|
||||||
|
OBJS = ${SRCS:.java=.class}
|
||||||
|
|
||||||
|
TARGET = package
|
||||||
|
|
||||||
|
.SUFFIXES: .java .class
|
||||||
|
|
||||||
|
all: $(CLASSDIR) $(TARGET)
|
||||||
|
|
||||||
|
install: $(TARGET)
|
||||||
|
foreach f ( $(OBJS) ) \
|
||||||
|
mv -f $$f $(CLASSDIR)/$$f \
|
||||||
|
end
|
||||||
|
|
||||||
|
#$(TARGET): $(OBJS)
|
||||||
|
$(TARGET):
|
||||||
|
$(JAVAC) $(JAVAFLAGS) *.java
|
||||||
|
$(CLASSDIR):
|
||||||
|
echo mkdir $(CLASSDIR)
|
||||||
|
- mkdir -p $(CLASSDIR)
|
||||||
|
|
||||||
|
#$(OBJS):
|
||||||
|
# $(JAVAC) $(JAVAFLAGS) *.java
|
||||||
|
#.java.class: $(SRCS)
|
||||||
|
# $(JAVAC) $(JAVAFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(CLASSDIR)/netscape/messaging/mime/*.class
|
||||||
|
rm -f $(CLASSDIR)/netscape/mime/*.class
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.net.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fileMIMEType class contains
|
||||||
|
* File MIME Content type and MIME encoding information.
|
||||||
|
* @author Prasad Yendluri
|
||||||
|
*/
|
||||||
|
public class fileMIMEType
|
||||||
|
{
|
||||||
|
public int content_type;
|
||||||
|
public String content_subtype;
|
||||||
|
public String content_params;
|
||||||
|
public String file_extn;
|
||||||
|
public String file_shortname;
|
||||||
|
public int mime_encoding = MIMEBodyPart.BASE64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a fileMIMEType object.
|
||||||
|
* Default constructor for the fileMIMEType class.
|
||||||
|
*/
|
||||||
|
public fileMIMEType ()
|
||||||
|
{
|
||||||
|
content_type = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// log.java
|
||||||
|
// Carson Lee
|
||||||
|
// Log class
|
||||||
|
//
|
||||||
|
|
||||||
|
package netscape.messaging.mime;
|
||||||
|
|
||||||
|
//import java.io.*;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
|
public class log
|
||||||
|
{
|
||||||
|
// defines
|
||||||
|
final static String errorLogFilename = "nsmail.log";
|
||||||
|
final static String spaces = " ";
|
||||||
|
static boolean bLogOn = true;
|
||||||
|
static boolean bTimestampOn = true;
|
||||||
|
static BufferedWriter errorLog;
|
||||||
|
|
||||||
|
public static void init()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( errorLog == null )
|
||||||
|
errorLog = new BufferedWriter( new FileWriter( errorLogFilename, true ), 1024 );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void close()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( errorLog != null )
|
||||||
|
{
|
||||||
|
errorLog.flush();
|
||||||
|
errorLog.close();
|
||||||
|
errorLog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void finalize()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void errorLog( String message )
|
||||||
|
{
|
||||||
|
if ( !bLogOn || message == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( errorLog == null )
|
||||||
|
init();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// option to turn off timestamp, it's expensive to use
|
||||||
|
if ( bTimestampOn )
|
||||||
|
{
|
||||||
|
Date timeStamp = new Date();
|
||||||
|
timeStamp.setTime( System.currentTimeMillis() );
|
||||||
|
errorLog.write( timeStamp.toString(), 0, 28 );
|
||||||
|
errorLog.write( spaces, 0, 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
errorLog.write( message, 0, message.length() );
|
||||||
|
errorLog.newLine();
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void timestampOn() { bTimestampOn = true; }
|
||||||
|
public static void timestampOff() { bTimestampOn = false; }
|
||||||
|
public static void LogOn() { bLogOn = true; }
|
||||||
|
public static void LogOff() { bLogOn = false; }
|
||||||
|
|
||||||
|
|
||||||
|
} // eof log.java
|
|
@ -0,0 +1,32 @@
|
||||||
|
This directory contains an example program that demonstrates the use of the Netscape
|
||||||
|
Messaging MIME Parser java API.
|
||||||
|
|
||||||
|
To compile and run:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
(1) Make sure CLASSPATH includes the msg-sdk jar file (proapi.jar).
|
||||||
|
When installed proapi.jar is located at <install-root>/packages/proapi.jar.
|
||||||
|
Make sure CLASSPATH also includes the directory you are compiling in.
|
||||||
|
|
||||||
|
(2) Compile: javac *.java
|
||||||
|
(3) Run: java testApp
|
||||||
|
|
||||||
|
This shows the usage:
|
||||||
|
|
||||||
|
usage: java testApp <file-name> [D]
|
||||||
|
|
||||||
|
Explanation of parameters above:
|
||||||
|
<file-name>: file with MIME message to parse
|
||||||
|
[D] For dynamic parsing (default).
|
||||||
|
Any other values performs static parsing
|
||||||
|
|
||||||
|
(4) Run again with appropriate parameters. For example:
|
||||||
|
|
||||||
|
java testApp mime1.txt D
|
||||||
|
|
||||||
|
NOTE: The other two program testAppStr.java and
|
||||||
|
testAppStrLoop.java have minor differences with
|
||||||
|
testApp.java.
|
||||||
|
|
||||||
|
testAppStr.java passes the entire input stream to the parser in one shot.
|
||||||
|
testAppStrLoop.java Demonstrate parsing > 1 messages with the same parser object.
|
|
@ -0,0 +1,287 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
public class myDataSink extends MIMEDataSink
|
||||||
|
{
|
||||||
|
FileOutputStream out;
|
||||||
|
FileOutputStream out2;
|
||||||
|
int m_nChunkNo;
|
||||||
|
String contentType;
|
||||||
|
int basicPartCount, msgPartCount, msgCount, multiPartCount;
|
||||||
|
|
||||||
|
public myDataSink()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
out = new FileOutputStream ("output.log");
|
||||||
|
out2 = new FileOutputStream ("list2.com");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
// Ignore if we can't create a log file
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nChunkNo = 0;
|
||||||
|
msgCount=0;
|
||||||
|
basicPartCount=0;
|
||||||
|
msgPartCount=0;
|
||||||
|
multiPartCount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log (String s)
|
||||||
|
{
|
||||||
|
System.out.println (s);
|
||||||
|
String ss = s + "\r\n";
|
||||||
|
|
||||||
|
if (out != null)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
out.write (ss.getBytes());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
// Ignore if we can't write to log file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void header (Object callbackObject, byte[] name, byte[] value)
|
||||||
|
{
|
||||||
|
String s;
|
||||||
|
|
||||||
|
if (callbackObject != null)
|
||||||
|
{
|
||||||
|
s = (String) callbackObject;
|
||||||
|
|
||||||
|
log (s + "> header() --> name = [" + new String(name) + "] value = [" +
|
||||||
|
new String (value) + "]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log ("header() --> name = [" + new String(name) + "] value = [" +
|
||||||
|
new String (value) + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeader (Object callbackObject, byte[] name, byte[] value)
|
||||||
|
{
|
||||||
|
String s;
|
||||||
|
|
||||||
|
if (callbackObject != null)
|
||||||
|
{
|
||||||
|
s = (String) callbackObject;
|
||||||
|
|
||||||
|
log (s + "> addHeader() --> name = [" + new String(name) + "] value = [" +
|
||||||
|
new String (value) + "]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log ("addHeader() --> name = [" + new String(name) + "] value = [" +
|
||||||
|
new String (value) + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void endMessageHeader (Object callbackObject)
|
||||||
|
{
|
||||||
|
String s;
|
||||||
|
|
||||||
|
if (callbackObject != null)
|
||||||
|
{
|
||||||
|
s = (String) callbackObject;
|
||||||
|
|
||||||
|
log (s + " endMessageHeader()");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log ("???? endMessageHeader()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentType (Object callbackObject, byte[] bContentType)
|
||||||
|
{
|
||||||
|
contentType = new String (bContentType);
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s + "> contentType() --> [" + contentType + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentSubType (Object callbackObject, byte[] contentSubType)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s + "> contentSubType() --> [" + new String (contentSubType) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentTypeParams (Object callbackObject, byte[] contentTypeParams)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentTypeParams() --> [" + new String (contentTypeParams) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentID (Object callbackObject, byte[] contentID)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentID() --> [" + new String (contentID) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentMD5 (Object callbackObject, byte[] contentMD5)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentMD5() --> + [" + new String (contentMD5) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentDisposition (Object callbackObject, int nContentDisposition)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentDisposition() --> [" + nContentDisposition + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentDispParams (Object callbackObject, byte[] contentDispParams)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentDispParams() --> [" + new String (contentDispParams) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentDescription (Object callbackObject, byte[] contentDescription)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentDescription() --> [" + new String (contentDescription) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void contentEncoding (Object callbackObject, int nContentEncoding)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> contentEncoding() --> [" + nContentEncoding + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object startMessage ()
|
||||||
|
{
|
||||||
|
String s = new String ("message" + ++msgCount);
|
||||||
|
|
||||||
|
log ("startMessage() " + msgCount);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endMessage (Object callbackObject)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> endMessage()");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (out != null)
|
||||||
|
out.close();
|
||||||
|
if (out2 != null)
|
||||||
|
out2.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object startBasicPart ()
|
||||||
|
{
|
||||||
|
String s = new String ("BasicPart" + ++basicPartCount);
|
||||||
|
log ("startBasicPart() " + basicPartCount);
|
||||||
|
return s;
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bodyData (Object callbackObject, InputStream input, int len)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
|
||||||
|
log (s+ "> bodyData() --> len = " + len + " ChunkNo = " + m_nChunkNo++);
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if (contentType.equalsIgnoreCase ("Application"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int b = input.read(), i = 0; i < len && b != -1; b = input.read(), i++)
|
||||||
|
out2.write (b);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endBasicPart (Object callbackObject)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
|
||||||
|
log (s+ "> endBasicPart()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object startMultiPart ()
|
||||||
|
{
|
||||||
|
String s = new String ("MultiPart" + ++multiPartCount);
|
||||||
|
log ("startMultiPart() " + multiPartCount);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void boundary (Object callbackObject, byte[] boundary)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> boundary() --> [" + new String (boundary) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endMultiPart (Object callbackObject)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
|
||||||
|
log (s+ "> endMultiPart()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object startMessagePart ()
|
||||||
|
{
|
||||||
|
String s = new String ("MessagePart" + ++msgPartCount);
|
||||||
|
|
||||||
|
log ("startMessagePart() " + msgPartCount);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endMessagePart (Object callbackObject)
|
||||||
|
{
|
||||||
|
String s = (String) callbackObject;
|
||||||
|
log (s+ "> endMessagePart()");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,368 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This example programs demonstrates the use of Static and
|
||||||
|
* Dynamic MIME Parser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class testApp
|
||||||
|
{
|
||||||
|
byte b[];
|
||||||
|
FileOutputStream logfile;
|
||||||
|
int m_nFileNo;
|
||||||
|
|
||||||
|
public testApp()
|
||||||
|
{
|
||||||
|
b = new byte[100000];
|
||||||
|
m_nFileNo=0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile = new FileOutputStream ("testapp.log");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showObject (Object o)
|
||||||
|
{
|
||||||
|
InputStream in = null;
|
||||||
|
|
||||||
|
if (o == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (o instanceof MIMEMessage)
|
||||||
|
{
|
||||||
|
output ("--------------- Start Mime Message ---------------\n");
|
||||||
|
|
||||||
|
MIMEMessage m = (MIMEMessage) o;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("message header = [" + h[i].getLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* message body type = " + m.getBodyType() + "\n");
|
||||||
|
output ("* message content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* message content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* message content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
|
||||||
|
showObject (m.getBody(false));
|
||||||
|
output ("---------------- End Mime Message -----------------\n");
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (o instanceof MIMEBasicPart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime BasicPart -------------------\n");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEBasicPart m = (MIMEBasicPart) o;
|
||||||
|
in = m.getBodyData();
|
||||||
|
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (m.getMessageDataLen() < 100000)
|
||||||
|
len = in.read (b);
|
||||||
|
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("basic header = [" + h[i].getLine() );
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* basicpart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* basicpart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* basicpart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* basicpart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* basicpart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* basicpart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* basicpart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
output ("* basicpart content MD5 = " + m.getContentMD5() + "\n");
|
||||||
|
output ("* basicpart getbodysize() = " + m.getSize() + "\n");
|
||||||
|
output ("* basicpart content encoding = " + m.getContentEncoding() + "\n");
|
||||||
|
|
||||||
|
output (">>>>>>>>>>>>>>>>>>>> start data >>>>>>>>>>>>>>>>>>>\n");
|
||||||
|
|
||||||
|
// base64
|
||||||
|
if (m.getContentEncoding() == 0)
|
||||||
|
output ("[BASE64 BINARY DATA]");
|
||||||
|
// QP
|
||||||
|
else if (m.getContentEncoding() == 1)
|
||||||
|
output ("[QP DATA]");
|
||||||
|
// text
|
||||||
|
else
|
||||||
|
output (b, len);
|
||||||
|
|
||||||
|
output ("\n>>>>>>>>>>>>>>>>>>>> end data >>>>>>>>>>>>>>>>>>>>\n");
|
||||||
|
|
||||||
|
// base64
|
||||||
|
if (m.getContentEncoding() == 1 && m.getMessageDataLen() < 100000)
|
||||||
|
{
|
||||||
|
FileOutputStream out = new FileOutputStream ("bodydata" + m_nFileNo++ + ".out");
|
||||||
|
out.write (b, 0, m.getMessageDataLen());
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime BasicPart -------------------\n");
|
||||||
|
}
|
||||||
|
else if (o instanceof MIMEMultiPart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime MultiPart -------------------\n");
|
||||||
|
|
||||||
|
MIMEMultiPart m = (MIMEMultiPart) o;
|
||||||
|
int count = m.getBodyPartCount();
|
||||||
|
|
||||||
|
// debug
|
||||||
|
output ("* multipart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* multipart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* multipart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* multipart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* multipart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* multipart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* multipart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object part = m.getBodyPart(i, false);
|
||||||
|
showObject (part);
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime MultiPart ------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (o instanceof MIMEMessagePart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime MessagePart ----------------\n");
|
||||||
|
|
||||||
|
MIMEMessagePart m = (MIMEMessagePart) o;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEMessage part = m.getMessage(false);
|
||||||
|
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("messagepart header = [" + h[i].getLine() );
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* messagepart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* messagepart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* messagepart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* messagepart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* messagepart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* messagepart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* messagepart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
output ("* messagepart content encoding = " + m.getContentEncoding() + "\n");
|
||||||
|
|
||||||
|
showObject (part);
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime MessagePart -----------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parseFileMessage (String filename, boolean bDynamic)
|
||||||
|
{
|
||||||
|
if (!bDynamic) // perform Static Parsing
|
||||||
|
{
|
||||||
|
MIMEParser p = new MIMEParser();
|
||||||
|
|
||||||
|
output ("============== Begin Static Parsing " + filename + " ============\n");
|
||||||
|
|
||||||
|
if (filename != null && p != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInputStream input = new FileInputStream (filename);
|
||||||
|
showObject (p.parseEntireMessage (input));
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("\n=========== Parsing Complete " + filename + " =============\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else // perform Dynamic Parsing
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
myDataSink dataSink = new myDataSink();
|
||||||
|
MIMEDynamicParser p = new MIMEDynamicParser (dataSink);
|
||||||
|
FileInputStream input = new FileInputStream (filename);
|
||||||
|
byte[] buffer = new byte[256];
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
output ("============== Begin Dynamic Parsing " + filename + " ============\n");
|
||||||
|
|
||||||
|
p.beginParse();
|
||||||
|
|
||||||
|
bytesRead = input.read (buffer);
|
||||||
|
|
||||||
|
while (bytesRead > 0)
|
||||||
|
{
|
||||||
|
p.parse (buffer);
|
||||||
|
bytesRead = input.read (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.endParse();
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
//showObject (dataSink.m_mimeMessage);
|
||||||
|
|
||||||
|
output ("\n=========== Parsing Complete " + filename + " =============\n\n");
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // bDynamic
|
||||||
|
|
||||||
|
} // parseFileMessage
|
||||||
|
|
||||||
|
|
||||||
|
void output (String s)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile.write (s.getBytes());
|
||||||
|
System.out.println (s);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void output (byte b[], int len)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile.write (b, 0, len);
|
||||||
|
System.out.println (new String (b, 0, len));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ MIAN ******************/
|
||||||
|
static public void main(String args[])
|
||||||
|
{
|
||||||
|
boolean bDynamic=true; // Dynamic Parsing by Default
|
||||||
|
String filename;
|
||||||
|
|
||||||
|
if (args.length < 1)
|
||||||
|
{
|
||||||
|
System.out.println("usage: java testApp <file-name> [D]");
|
||||||
|
System.out.println("example: java testApp mime1.txt");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = args[0];
|
||||||
|
|
||||||
|
if (args.length > 1 && !args[1].equalsIgnoreCase("D"))
|
||||||
|
{
|
||||||
|
bDynamic = false; // Switch to Static Parsing
|
||||||
|
}
|
||||||
|
|
||||||
|
log.init();
|
||||||
|
log.timestampOff();
|
||||||
|
testApp ta = new testApp();
|
||||||
|
|
||||||
|
// parse the message in the file
|
||||||
|
ta.parseFileMessage (filename, bDynamic);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,370 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This example programs demonstrates the use of Static and
|
||||||
|
* Dynamic MIME Parser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class testAppStr
|
||||||
|
{
|
||||||
|
byte b[];
|
||||||
|
FileOutputStream logfile;
|
||||||
|
int m_nFileNo;
|
||||||
|
|
||||||
|
public testAppStr()
|
||||||
|
{
|
||||||
|
b = new byte[100000];
|
||||||
|
m_nFileNo=0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile = new FileOutputStream ("testapp.log");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showObject (Object o)
|
||||||
|
{
|
||||||
|
InputStream in = null;
|
||||||
|
|
||||||
|
if (o == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (o instanceof MIMEMessage)
|
||||||
|
{
|
||||||
|
output ("--------------- Start Mime Message ---------------\n");
|
||||||
|
|
||||||
|
MIMEMessage m = (MIMEMessage) o;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("message header = [" + h[i].getLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* message body type = " + m.getBodyType() + "\n");
|
||||||
|
output ("* message content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* message content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* message content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
|
||||||
|
showObject (m.getBody(false));
|
||||||
|
output ("---------------- End Mime Message -----------------\n");
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (o instanceof MIMEBasicPart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime BasicPart -------------------\n");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEBasicPart m = (MIMEBasicPart) o;
|
||||||
|
in = m.getBodyData();
|
||||||
|
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (m.getMessageDataLen() < 100000)
|
||||||
|
len = in.read (b);
|
||||||
|
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("basic header = [" + h[i].getLine() );
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* basicpart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* basicpart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* basicpart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* basicpart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* basicpart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* basicpart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* basicpart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
output ("* basicpart content MD5 = " + m.getContentMD5() + "\n");
|
||||||
|
output ("* basicpart getbodysize() = " + m.getSize() + "\n");
|
||||||
|
output ("* basicpart content encoding = " + m.getContentEncoding() + "\n");
|
||||||
|
|
||||||
|
output (">>>>>>>>>>>>>>>>>>>> start data >>>>>>>>>>>>>>>>>>>\n");
|
||||||
|
|
||||||
|
// base64
|
||||||
|
if (m.getContentEncoding() == 0)
|
||||||
|
output ("[BASE64 BINARY DATA]");
|
||||||
|
// QP
|
||||||
|
else if (m.getContentEncoding() == 1)
|
||||||
|
output ("[QP DATA]");
|
||||||
|
// text
|
||||||
|
else
|
||||||
|
output (b, len);
|
||||||
|
|
||||||
|
output ("\n>>>>>>>>>>>>>>>>>>>> end data >>>>>>>>>>>>>>>>>>>>\n");
|
||||||
|
|
||||||
|
// base64
|
||||||
|
if (m.getContentEncoding() == 1 && m.getMessageDataLen() < 100000)
|
||||||
|
{
|
||||||
|
FileOutputStream out = new FileOutputStream ("bodydata" + m_nFileNo++ + ".out");
|
||||||
|
out.write (b, 0, m.getMessageDataLen());
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime BasicPart -------------------\n");
|
||||||
|
}
|
||||||
|
else if (o instanceof MIMEMultiPart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime MultiPart -------------------\n");
|
||||||
|
|
||||||
|
MIMEMultiPart m = (MIMEMultiPart) o;
|
||||||
|
int count = m.getBodyPartCount();
|
||||||
|
|
||||||
|
// debug
|
||||||
|
output ("* multipart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* multipart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* multipart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* multipart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* multipart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* multipart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* multipart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object part = m.getBodyPart(i, false);
|
||||||
|
showObject (part);
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime MultiPart ------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (o instanceof MIMEMessagePart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime MessagePart ----------------\n");
|
||||||
|
|
||||||
|
MIMEMessagePart m = (MIMEMessagePart) o;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEMessage part = m.getMessage(false);
|
||||||
|
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("messagepart header = [" + h[i].getLine() );
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* messagepart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* messagepart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* messagepart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* messagepart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* messagepart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* messagepart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* messagepart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
output ("* messagepart content encoding = " + m.getContentEncoding() + "\n");
|
||||||
|
|
||||||
|
showObject (part);
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime MessagePart -----------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parseFileMessage (String filename, boolean bDynamic)
|
||||||
|
{
|
||||||
|
if (!bDynamic) // perform Static Parsing
|
||||||
|
{
|
||||||
|
MIMEParser p = new MIMEParser();
|
||||||
|
|
||||||
|
output ("============== Begin Static Parsing " + filename + " ============\n");
|
||||||
|
|
||||||
|
if (filename != null && p != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInputStream input = new FileInputStream (filename);
|
||||||
|
showObject (p.parseEntireMessage (input));
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("\n=========== Parsing Complete " + filename + " =============\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else // perform Dynamic Parsing
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
myDataSink dataSink = new myDataSink();
|
||||||
|
//MIMEDynamicParser p = new MIMEDynamicParser (dataSink, true, true);
|
||||||
|
MIMEDynamicParser p = new MIMEDynamicParser (dataSink);
|
||||||
|
FileInputStream input = new FileInputStream (filename);
|
||||||
|
byte[] buffer = new byte[256];
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
output ("============== Begin Dynamic Parsing " + filename + " ============\n");
|
||||||
|
|
||||||
|
p.beginParse();
|
||||||
|
|
||||||
|
p.parse (input);
|
||||||
|
|
||||||
|
//bytesRead = input.read (buffer);
|
||||||
|
//while (bytesRead > 0)
|
||||||
|
//{
|
||||||
|
// p.parse (buffer);
|
||||||
|
// bytesRead = input.read (buffer);
|
||||||
|
//}
|
||||||
|
|
||||||
|
p.endParse();
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
//showObject (dataSink.m_mimeMessage);
|
||||||
|
|
||||||
|
output ("\n=========== Parsing Complete " + filename + " =============\n\n");
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // bDynamic
|
||||||
|
|
||||||
|
} // parseFileMessage
|
||||||
|
|
||||||
|
|
||||||
|
void output (String s)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile.write (s.getBytes());
|
||||||
|
System.out.println (s);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void output (byte b[], int len)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile.write (b, 0, len);
|
||||||
|
System.out.println (new String (b, 0, len));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ MIAN ******************/
|
||||||
|
static public void main(String args[])
|
||||||
|
{
|
||||||
|
boolean bDynamic=true; // Dynamic Parsing by Default
|
||||||
|
String filename;
|
||||||
|
|
||||||
|
if (args.length < 1)
|
||||||
|
{
|
||||||
|
System.out.println("usage: java testAppStr <file-name> [D]");
|
||||||
|
System.out.println("example: java testAppStr mime1.txt");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = args[0];
|
||||||
|
|
||||||
|
if (args.length > 1 && !args[1].equalsIgnoreCase("D"))
|
||||||
|
{
|
||||||
|
bDynamic = false; // Switch to Static Parsing
|
||||||
|
}
|
||||||
|
|
||||||
|
log.init();
|
||||||
|
log.timestampOff();
|
||||||
|
testAppStr ta = new testAppStr();
|
||||||
|
|
||||||
|
// parse the message in the file
|
||||||
|
ta.parseFileMessage (filename, bDynamic);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,386 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This example programs demonstrates the use of Static and
|
||||||
|
* Dynamic MIME Parser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import netscape.messaging.mime.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class testAppStrLoop
|
||||||
|
{
|
||||||
|
byte b[];
|
||||||
|
FileOutputStream logfile;
|
||||||
|
int m_nFileNo;
|
||||||
|
public myDataSink dataSink = null;
|
||||||
|
public MIMEDynamicParser dp = null;
|
||||||
|
|
||||||
|
public testAppStrLoop()
|
||||||
|
{
|
||||||
|
b = new byte[100000];
|
||||||
|
m_nFileNo=0;
|
||||||
|
dataSink = null;
|
||||||
|
dp = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile = new FileOutputStream ("testapp.log");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showObject (Object o)
|
||||||
|
{
|
||||||
|
InputStream in = null;
|
||||||
|
|
||||||
|
if (o == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (o instanceof MIMEMessage)
|
||||||
|
{
|
||||||
|
output ("--------------- Start Mime Message ---------------\n");
|
||||||
|
|
||||||
|
MIMEMessage m = (MIMEMessage) o;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("message header = [" + h[i].getLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* message body type = " + m.getBodyType() + "\n");
|
||||||
|
output ("* message content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* message content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* message content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
|
||||||
|
showObject (m.getBody(false));
|
||||||
|
output ("---------------- End Mime Message -----------------\n");
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (o instanceof MIMEBasicPart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime BasicPart -------------------\n");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEBasicPart m = (MIMEBasicPart) o;
|
||||||
|
in = m.getBodyData();
|
||||||
|
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (m.getMessageDataLen() < 100000)
|
||||||
|
len = in.read (b);
|
||||||
|
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("basic header = [" + h[i].getLine() );
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* basicpart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* basicpart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* basicpart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* basicpart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* basicpart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* basicpart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* basicpart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
output ("* basicpart content MD5 = " + m.getContentMD5() + "\n");
|
||||||
|
output ("* basicpart getbodysize() = " + m.getSize() + "\n");
|
||||||
|
output ("* basicpart content encoding = " + m.getContentEncoding() + "\n");
|
||||||
|
|
||||||
|
output (">>>>>>>>>>>>>>>>>>>> start data >>>>>>>>>>>>>>>>>>>\n");
|
||||||
|
|
||||||
|
// base64
|
||||||
|
if (m.getContentEncoding() == 0)
|
||||||
|
output ("[BASE64 BINARY DATA]");
|
||||||
|
// QP
|
||||||
|
else if (m.getContentEncoding() == 1)
|
||||||
|
output ("[QP DATA]");
|
||||||
|
// text
|
||||||
|
else
|
||||||
|
output (b, len);
|
||||||
|
|
||||||
|
output ("\n>>>>>>>>>>>>>>>>>>>> end data >>>>>>>>>>>>>>>>>>>>\n");
|
||||||
|
|
||||||
|
// base64
|
||||||
|
if (m.getContentEncoding() == 1 && m.getMessageDataLen() < 100000)
|
||||||
|
{
|
||||||
|
FileOutputStream out = new FileOutputStream ("bodydata" + m_nFileNo++ + ".out");
|
||||||
|
out.write (b, 0, m.getMessageDataLen());
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime BasicPart -------------------\n");
|
||||||
|
}
|
||||||
|
else if (o instanceof MIMEMultiPart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime MultiPart -------------------\n");
|
||||||
|
|
||||||
|
MIMEMultiPart m = (MIMEMultiPart) o;
|
||||||
|
int count = m.getBodyPartCount();
|
||||||
|
|
||||||
|
// debug
|
||||||
|
output ("* multipart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* multipart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* multipart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* multipart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* multipart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* multipart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* multipart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object part = m.getBodyPart(i, false);
|
||||||
|
showObject (part);
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime MultiPart ------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (o instanceof MIMEMessagePart)
|
||||||
|
{
|
||||||
|
output ("------------------- Start Mime MessagePart ----------------\n");
|
||||||
|
|
||||||
|
MIMEMessagePart m = (MIMEMessagePart) o;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MIMEMessage part = m.getMessage(false);
|
||||||
|
|
||||||
|
Header[] h = m.getAllHeaders();
|
||||||
|
|
||||||
|
if (h != null)
|
||||||
|
for (int i=0; h != null && i < h.length; i++)
|
||||||
|
{
|
||||||
|
output ("messagepart header = [" + h[i].getLine() );
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("* messagepart content type = " + m.getContentType() + "\n");
|
||||||
|
output ("* messagepart content subtype = " + m.getContentSubType() + "\n");
|
||||||
|
output ("* messagepart content type param = " + m.getContentTypeParams() + "\n");
|
||||||
|
output ("* messagepart content ID = " + m.getContentID() + "\n");
|
||||||
|
output ("* messagepart content Disposition = " + m.getContentDisposition() + "\n");
|
||||||
|
output ("* messagepart content Disposition params = " + m.getContentDispParams() + "\n");
|
||||||
|
output ("* messagepart content Description = " + m.getContentDescription() + "\n");
|
||||||
|
output ("* messagepart content encoding = " + m.getContentEncoding() + "\n");
|
||||||
|
|
||||||
|
showObject (part);
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
output (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("------------------- End Mime MessagePart -----------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parseFileMessage (String filename, boolean bDynamic)
|
||||||
|
{
|
||||||
|
if (!bDynamic) // perform Static Parsing
|
||||||
|
{
|
||||||
|
MIMEParser p = new MIMEParser();
|
||||||
|
|
||||||
|
output ("============== Begin Static Parsing " + filename + " ============\n");
|
||||||
|
|
||||||
|
if (filename != null && p != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInputStream input = new FileInputStream (filename);
|
||||||
|
showObject (p.parseEntireMessage (input));
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output ("\n=========== Parsing Complete " + filename + " =============\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else // perform Dynamic Parsing
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (dataSink == null)
|
||||||
|
dataSink = new myDataSink();
|
||||||
|
if (dp == null)
|
||||||
|
dp = new MIMEDynamicParser (dataSink);
|
||||||
|
FileInputStream input = new FileInputStream (filename);
|
||||||
|
byte[] buffer = new byte[256];
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
output ("============== Begin Dynamic Parsing " + filename + " ============\n");
|
||||||
|
|
||||||
|
dp.beginParse();
|
||||||
|
|
||||||
|
dp.parse (input);
|
||||||
|
|
||||||
|
//bytesRead = input.read (buffer);
|
||||||
|
//while (bytesRead > 0)
|
||||||
|
//{
|
||||||
|
// p.parse (buffer);
|
||||||
|
// bytesRead = input.read (buffer);
|
||||||
|
//}
|
||||||
|
|
||||||
|
dp.endParse();
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
//showObject (dataSink.m_mimeMessage);
|
||||||
|
|
||||||
|
output ("\n=========== Parsing Complete " + filename + " =============\n\n");
|
||||||
|
}
|
||||||
|
catch (MIMEException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // bDynamic
|
||||||
|
|
||||||
|
} // parseFileMessage
|
||||||
|
|
||||||
|
|
||||||
|
void output (String s)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile.write (s.getBytes());
|
||||||
|
System.out.println (s);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void output (byte b[], int len)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logfile.write (b, 0, len);
|
||||||
|
System.out.println (new String (b, 0, len));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println (e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ MIAN ******************/
|
||||||
|
static public void main(String args[])
|
||||||
|
{
|
||||||
|
boolean bDynamic=true; // Dynamic Parsing by Default
|
||||||
|
String filename=null;
|
||||||
|
String filename2=null;
|
||||||
|
|
||||||
|
if (args.length < 1)
|
||||||
|
{
|
||||||
|
System.out.println("usage: java testAppStrLoop <file-name> [D]");
|
||||||
|
System.out.println("example: java testAppStrLoop mime1.txt");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
System.out.println("args count = " + args.length);
|
||||||
|
|
||||||
|
filename = args[0];
|
||||||
|
|
||||||
|
if (args.length > 2)
|
||||||
|
{
|
||||||
|
filename2 = args[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length >= 2 && !args[args.length-1].equalsIgnoreCase("D"))
|
||||||
|
{
|
||||||
|
bDynamic = false; // Switch to Static Parsing
|
||||||
|
}
|
||||||
|
|
||||||
|
log.init();
|
||||||
|
log.timestampOff();
|
||||||
|
testAppStrLoop ta = new testAppStrLoop();
|
||||||
|
|
||||||
|
// parse the message in the file
|
||||||
|
ta.parseFileMessage (filename, bDynamic);
|
||||||
|
|
||||||
|
if (args.length > 2)
|
||||||
|
ta.parseFileMessage (filename2, bDynamic);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Helper class for doing C-runtime equivalent operations.
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Common
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*Converts a byte array of specified length into an int.
|
||||||
|
*/
|
||||||
|
public final int atoi( byte[] in_string )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int n;
|
||||||
|
int sign;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Move past any leading spaces.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
for ( i = 0; Character.isSpaceChar((char)in_string[i]) &&
|
||||||
|
i < in_string.length; i++ )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sign = (in_string[i] == '-') ? -1 : 1;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Store the sign of the number.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( in_string[i] == '+' || in_string[i] == '-' )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( n = 0; Character.isDigit((char)in_string[i]) &&
|
||||||
|
i < in_string.length; i++ )
|
||||||
|
{
|
||||||
|
n = 10 * n + ( in_string[i] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Converts an integer into its ASCII representation.
|
||||||
|
*/
|
||||||
|
public final int itoa( int in_number, byte[] io_string )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int sign;
|
||||||
|
|
||||||
|
if ((sign = in_number) < 0)
|
||||||
|
{
|
||||||
|
in_number = -in_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
io_string[i++] = (byte)(in_number % 10 + '0');
|
||||||
|
}
|
||||||
|
while ((in_number /= 10) > 0);
|
||||||
|
|
||||||
|
if ( sign < 0 )
|
||||||
|
{
|
||||||
|
io_string[i++] = '-';
|
||||||
|
}
|
||||||
|
reverse(io_string, i );
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Helper used by itoa.
|
||||||
|
*/
|
||||||
|
protected final void reverse( byte[] io_string, int in_length )
|
||||||
|
{
|
||||||
|
int c, i, j;
|
||||||
|
|
||||||
|
for ( i = 0, j = in_length - 1; i < j; i++, j-- )
|
||||||
|
{
|
||||||
|
c = io_string[i];
|
||||||
|
io_string[i] = io_string[j];
|
||||||
|
io_string[j] = (byte)c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,633 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Class for conducting IO with a server. It communicates directly<br>
|
||||||
|
*with the input and output streams associated with the socket connected to<br>
|
||||||
|
*the ESMTP server. It performs the handling of synchronous versus<br>
|
||||||
|
*asynchronous methods. It also handles PIPELINING (batching) of commands if<br>
|
||||||
|
*the user chose this at connection time and the ESMTP server also supports<br>
|
||||||
|
*PIPELINING. This class also initializes and manages the authentication and<br>
|
||||||
|
*security objects.<br>
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class IO
|
||||||
|
{
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Data members used for network communication
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private Socket m_socket;
|
||||||
|
private BufferedInputStream m_inStream;
|
||||||
|
private BufferedOutputStream m_outStream;
|
||||||
|
|
||||||
|
private int m_timeout;
|
||||||
|
private final static byte[] m_newline = { '\r', '\n' };
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Error messages.
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected final static String errNotConnected =
|
||||||
|
new String("Must connect to server");
|
||||||
|
protected final static String errAlreadyConnected =
|
||||||
|
new String("Already connected to server");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Constructor for the IO object. Initializes all data members<br>
|
||||||
|
*/
|
||||||
|
public IO()
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Initialize data members.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
m_socket = null;
|
||||||
|
m_inStream = null;
|
||||||
|
m_outStream = null;
|
||||||
|
m_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect( String in_server, int in_portNumber ) throws IOException
|
||||||
|
{
|
||||||
|
connect( in_server, in_portNumber, 1024, 1024 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Open a communication channel with the server. An input stream<br>
|
||||||
|
*is initialized for receiving data from the server and an output stream is<br>
|
||||||
|
*initialized for send data to the server.<br>
|
||||||
|
*@param in_szServer Specifies the ESMTP server to connect to.
|
||||||
|
*@param in_portNumber Specifies the port used to communicate with.
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void connect( String in_server,
|
||||||
|
int in_portNumber,
|
||||||
|
int in_inStreamBuf,
|
||||||
|
int in_outStreamBuf ) throws IOException
|
||||||
|
{
|
||||||
|
if ( m_socket != null )
|
||||||
|
{
|
||||||
|
throw new IOException( errAlreadyConnected );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Initialize counters and flags.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Initializes the socket, input buffer and output buffer.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
m_socket = new Socket( in_server, in_portNumber );
|
||||||
|
m_inStream = new BufferedInputStream( m_socket.getInputStream(), in_inStreamBuf );
|
||||||
|
m_outStream = new BufferedOutputStream( m_socket.getOutputStream(), in_outStreamBuf );
|
||||||
|
setTimeout( m_timeout );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Initialize counters and flags.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
m_inStream = null;
|
||||||
|
m_outStream = null;
|
||||||
|
|
||||||
|
if ( m_socket != null )
|
||||||
|
{
|
||||||
|
m_socket.close();
|
||||||
|
m_socket = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Determines if a connection is currently open.
|
||||||
|
*/
|
||||||
|
private boolean isConnected()
|
||||||
|
{
|
||||||
|
if ( m_inStream == null || m_outStream == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Fill a byte array buffer.
|
||||||
|
*/
|
||||||
|
public int read( byte[] out_buffer, int in_offset, int in_length ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( in_length > out_buffer.length )
|
||||||
|
{
|
||||||
|
in_length = out_buffer.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Returns -1 if the specified amount of data is not available.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( (m_timeout == -1) && (m_inStream.available() < in_length) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Read the data from the input stream.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
return m_inStream.read( out_buffer, in_offset, in_length );
|
||||||
|
}
|
||||||
|
catch( InterruptedIOException e )
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Reads a line of data from the input stream.
|
||||||
|
*/
|
||||||
|
public int readLine( byte[] out_buffer ) throws IOException
|
||||||
|
{
|
||||||
|
return readLine( out_buffer, 0, out_buffer.length );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Reads a line of data from the input stream.
|
||||||
|
*/
|
||||||
|
public int readLine( byte[] out_buffer, int in_offset, int in_length ) throws IOException
|
||||||
|
{
|
||||||
|
int l_byteCount = 0;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_inStream.mark( in_length );
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Read the data from the input stream.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( (m_timeout == -1) && (m_inStream.available() == 0) )
|
||||||
|
{
|
||||||
|
m_inStream.reset();
|
||||||
|
throw new InterruptedIOException();
|
||||||
|
}
|
||||||
|
|
||||||
|
out_buffer[in_offset] = (byte)m_inStream.read();
|
||||||
|
in_offset++;
|
||||||
|
l_byteCount++;
|
||||||
|
}
|
||||||
|
while( out_buffer[in_offset-1] != '\n' );
|
||||||
|
|
||||||
|
return ( l_byteCount - 2 );
|
||||||
|
}
|
||||||
|
catch( InterruptedIOException e )
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read's in in_bytes of data into in_data
|
||||||
|
* @param in_data The storage for the data read in
|
||||||
|
* @param in_bytes The maximum number of bytes to read
|
||||||
|
* @param int The actual number of bytes read
|
||||||
|
*/
|
||||||
|
public int read(byte[] in_data, int in_bytes) throws IOException
|
||||||
|
{
|
||||||
|
int l_bytesRead = 0;
|
||||||
|
int l_totalBytes = 0;
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while(l_totalBytes < in_bytes)
|
||||||
|
{
|
||||||
|
l_bytesRead = m_inStream.read(in_data, l_totalBytes, in_bytes - l_totalBytes);
|
||||||
|
if(l_bytesRead == -1)
|
||||||
|
{
|
||||||
|
if(l_totalBytes ==0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l_totalBytes += l_bytesRead;
|
||||||
|
}
|
||||||
|
return l_totalBytes;
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read's a line of data and stores it in m_responseBuffer
|
||||||
|
* NOTE: This function strips off /r/n
|
||||||
|
*/
|
||||||
|
public void readLine(StringBuffer in_line) throws IOException
|
||||||
|
{
|
||||||
|
char l_nextChar = ' ';
|
||||||
|
boolean l_bLineRead = false;
|
||||||
|
in_line.setLength(0);
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while(!l_bLineRead)
|
||||||
|
{
|
||||||
|
//Store a line of the server response
|
||||||
|
l_nextChar = (char)m_inStream.read();
|
||||||
|
if((l_nextChar == '\r') || (l_nextChar == '\n'))
|
||||||
|
{
|
||||||
|
m_inStream.mark(2);
|
||||||
|
l_nextChar = (char)m_inStream.read();
|
||||||
|
if(l_nextChar != '\n')
|
||||||
|
{
|
||||||
|
m_inStream.reset();
|
||||||
|
}
|
||||||
|
l_bLineRead = true;
|
||||||
|
}
|
||||||
|
else if(l_nextChar == -1)
|
||||||
|
{
|
||||||
|
throw new IOException("The socket has been closed unexpectedly.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in_line.append(l_nextChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void write( byte in_byte ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_outStream.write( in_byte );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void write( String in_buffer ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int l_length = in_buffer.length();
|
||||||
|
|
||||||
|
for ( int i = 0; i < l_length; i++ )
|
||||||
|
{
|
||||||
|
m_outStream.write( (byte)in_buffer.charAt(i) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void write( byte[] in_buffer ) throws IOException
|
||||||
|
{
|
||||||
|
write( in_buffer, 0, in_buffer.length );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void write( byte[] in_buffer, int in_offset, int in_length ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Send the command to the server
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
m_outStream.write( in_buffer, in_offset, in_length );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends client commands to IMAP server synchronously.
|
||||||
|
* @param in_szCommand The IMAP command to invoke on the server
|
||||||
|
* @return boolean TRUE if command executed, FALSE otherwise. Note: Does not
|
||||||
|
* indicate successful completion of the command, just that it has been invoked
|
||||||
|
* on the IMAP Server. You must look in in_command to find the server response
|
||||||
|
* once the sendCommand() call returns.
|
||||||
|
*/
|
||||||
|
public void write(Vector in_data) throws IOException
|
||||||
|
{
|
||||||
|
String l_dataString = null;
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for(int i = 0; i < in_data.size(); i++)
|
||||||
|
{
|
||||||
|
l_dataString = (String)in_data.elementAt(i);
|
||||||
|
if(l_dataString != null)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < l_dataString.length(); j++)
|
||||||
|
{
|
||||||
|
m_outStream.write((byte)l_dataString.charAt(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void send( String in_buffer, boolean in_bufferData ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int l_length = in_buffer.length();
|
||||||
|
|
||||||
|
for ( int i = 0; i < l_length; i++ )
|
||||||
|
{
|
||||||
|
m_outStream.write( (byte)in_buffer.charAt(i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outStream.write( m_newline );
|
||||||
|
|
||||||
|
if ( in_bufferData == false )
|
||||||
|
{
|
||||||
|
m_outStream.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void send( byte[] in_buffer, boolean in_bufferData ) throws IOException
|
||||||
|
{
|
||||||
|
send( in_buffer, 0, in_buffer.length, in_bufferData );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@exception IOException thrown if IOError.
|
||||||
|
*/
|
||||||
|
public void send( byte[] in_buffer,
|
||||||
|
int in_offset,
|
||||||
|
int in_length,
|
||||||
|
boolean in_bufferData ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_outStream.write( in_buffer, in_offset, in_length );
|
||||||
|
m_outStream.write( m_newline );
|
||||||
|
|
||||||
|
if ( in_bufferData == false )
|
||||||
|
{
|
||||||
|
m_outStream.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public void flush() throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Flush the output stream.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
m_outStream.flush();
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Sets the socket timeout for reading data from the socket input buffer.
|
||||||
|
*/
|
||||||
|
public void setTimeout( int in_timeout ) throws IOException
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// Make sure there is a valid connection.
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// We should be able to set timeouts while disconnected.
|
||||||
|
/*
|
||||||
|
if ( isConnected() == false )
|
||||||
|
{
|
||||||
|
throw new IOException(errNotConnected);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if ( in_timeout < -1 )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_timeout = in_timeout;
|
||||||
|
|
||||||
|
if ( isConnected() == true )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( m_timeout != -1 )
|
||||||
|
{
|
||||||
|
m_socket.setSoTimeout( m_timeout );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
# environment
|
||||||
|
#SHELL = /usr/bin/ksh
|
||||||
|
|
||||||
|
# commands
|
||||||
|
JAVAC = javac
|
||||||
|
ARCH = $(shell uname -s)
|
||||||
|
|
||||||
|
ifeq ($(ARCH), SunOS)
|
||||||
|
ARCH = SOLARIS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ARCH), HP-UX)
|
||||||
|
ARCH = HPUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
# java flags
|
||||||
|
DEBUGJAVAFLAG =
|
||||||
|
OPTJAVAFLAG = -d $(CLASSDIR)
|
||||||
|
JAVAFLAGS = $(OTHERJAVAFLAGS) $(OPTJAVAFLAG) $(DEBUGJAVAFLAG)
|
||||||
|
|
||||||
|
# files and directories
|
||||||
|
CLASSDIR = ../../../built/$(ARCH)/protocol
|
||||||
|
|
||||||
|
#CLASSPATH = .:$(CLASSDIR):$(JDKCLASSPATH)
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
IO.java \
|
||||||
|
Common.java
|
||||||
|
|
||||||
|
OBJS = ${SRCS:.java=.class}
|
||||||
|
|
||||||
|
TARGET = package
|
||||||
|
|
||||||
|
.SUFFIXES: .java .class
|
||||||
|
|
||||||
|
all: $(CLASSDIR) $(TARGET)
|
||||||
|
|
||||||
|
install: $(TARGET)
|
||||||
|
foreach f ( $(OBJS) ) \
|
||||||
|
mv -f $$f $(CLASSDIR)/$$f \
|
||||||
|
end
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CLASSDIR):
|
||||||
|
echo mkdir $(CLASSDIR)
|
||||||
|
- mkdir -p $(CLASSDIR)
|
||||||
|
|
||||||
|
.java.class: $(SRCS)
|
||||||
|
$(JAVAC) $(JAVAFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
echo $(ARCH)
|
||||||
|
rm -f ../../../built/$(ARCH)/netscape/messaging/*.class
|
||||||
|
|
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.smtp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*ISMTPSink is the interface for the response sink for all SMTP commands.
|
||||||
|
*<p>The ISMTPSink interface contains callback methods for each client call.
|
||||||
|
*The client’s processResponses call invokes the appropriate
|
||||||
|
*interface callback method.
|
||||||
|
*<p>To utilize the SMTP client object, you must extend this
|
||||||
|
*interface. As a convenience, the Messaging Access SDK provides the
|
||||||
|
*SMTPSink class, which implements the ISMTPSink interface.
|
||||||
|
*You can save a step by extending the SMTPSink class, or
|
||||||
|
*you can implement your own class based on the ISMTPSink
|
||||||
|
*interface. The constructor for the SMTPClient class takes an
|
||||||
|
*ISMTPSink interface as a parameter.
|
||||||
|
*<p>These methods return standard SMTP Response Codes, as defined in RFC 821.
|
||||||
|
*See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP"
|
||||||
|
*for more information. For detailed information about SMTP,
|
||||||
|
*see RFC 821. (For the URL, see "Where to Find More Information" in "About This Book.")
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ISMTPSink
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*Notification for the response to the BDAT command.
|
||||||
|
*Sends binary data chunks of the specified size to the server.
|
||||||
|
*When using the sendCommand method, send data with the data method
|
||||||
|
*and not with bdat.
|
||||||
|
*Note: bdat is not supported by Messaging Server 4.0. Use data instead.
|
||||||
|
*<p>See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#bdat
|
||||||
|
* @see #data
|
||||||
|
* @see #send
|
||||||
|
*/
|
||||||
|
public void bdat( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the connection to the server.
|
||||||
|
*<P>Connects to the server using the default port (25).
|
||||||
|
*See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#connect
|
||||||
|
* @see #quit
|
||||||
|
*/
|
||||||
|
public void connect( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the DATA command.
|
||||||
|
*Prepares to send data to the server. The sendCommand method requires
|
||||||
|
*sending data with the data method and not with bdat.
|
||||||
|
*For more information, see RFC 821 (URL: go to SMTP RFCs).
|
||||||
|
*See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#data
|
||||||
|
* @see #bdat
|
||||||
|
* @see #send
|
||||||
|
*/
|
||||||
|
public void data( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the EHLO command.
|
||||||
|
*Along with ehloComplete, returns extended server information.
|
||||||
|
*Can get extended server information (which can be multiline).
|
||||||
|
*See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_serverInfo Extension supported by the server.
|
||||||
|
* @see SMTPClient#ehlo
|
||||||
|
* @see #ehloComplete
|
||||||
|
*/
|
||||||
|
public void ehlo( int in_responseCode, StringBuffer in_serverInfo );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the EHLO command.
|
||||||
|
*Along with ehlo, returns extended server information.
|
||||||
|
* @see SMTPClient#ehlo
|
||||||
|
* @see #ehlo
|
||||||
|
*/
|
||||||
|
public void ehloComplete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Error notification.
|
||||||
|
*Called when an error occurs.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_errorMessage Text that describes the error.
|
||||||
|
* @exception SMTPServerException If a server response error occurs.
|
||||||
|
* @see SMTPClient#processResponses
|
||||||
|
*/
|
||||||
|
public void error( int in_responseCode, StringBuffer in_errorMessage ) throws SMTPServerException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the EXPN command.
|
||||||
|
*Along with expandComplete, gets the email address of the specified user.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_user User for whom to get an email address.
|
||||||
|
* @see SMTPClient#expand
|
||||||
|
* @see #expandComplete
|
||||||
|
*/
|
||||||
|
public void expand( int in_responseCode, StringBuffer in_user );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the EXPN command.
|
||||||
|
*Along with expand, gets the email address of the specified user.
|
||||||
|
* @see SMTPClient#expand
|
||||||
|
* @see #expand
|
||||||
|
*/
|
||||||
|
public void expandComplete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the HELP command.
|
||||||
|
*Along with helpComplete, gets help on the specified topic,
|
||||||
|
*which can be multiline.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_help Line of help text.
|
||||||
|
* @see SMTPClient#help
|
||||||
|
* @see #helpComplete
|
||||||
|
*/
|
||||||
|
public void help( int in_responseCode, StringBuffer in_help );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the HELP command.
|
||||||
|
*Along with help, gets help on a specified topic.
|
||||||
|
* @see SMTPClient#help
|
||||||
|
* @see #help
|
||||||
|
*/
|
||||||
|
public void helpComplete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the MAIL FROM command.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#mailFrom
|
||||||
|
* @see #rcptTo
|
||||||
|
*/
|
||||||
|
public void mailFrom( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the NOOP command.
|
||||||
|
*<P>Server responds to commands with a "still here" response.
|
||||||
|
*Sending the noop method does nothing except force this response.
|
||||||
|
*Can be used to maintain server connection, perhaps being issued
|
||||||
|
*at timed intervals to make sure that the server is still active.
|
||||||
|
*<p>Resets the autologout timer inside the server.
|
||||||
|
*Not needed by applications that do not need to maintain the connection.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#noop
|
||||||
|
*/
|
||||||
|
public void noop( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the QUIT command.
|
||||||
|
*Ends the session. If the session is in the Authentication state,
|
||||||
|
*the server closes the server connection. If the session is in
|
||||||
|
*the Transaction state, the server goes into the Update state
|
||||||
|
*and deletes any marked messages, and then quits.
|
||||||
|
* See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#quit
|
||||||
|
*/
|
||||||
|
public void quit( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the RCPT TO command.
|
||||||
|
*Gets the address of the recipient of the message. Called once for each
|
||||||
|
*recipient; should follow the SMTP_mailFrom function.
|
||||||
|
* See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#rcptTo
|
||||||
|
* @see #mailFrom
|
||||||
|
*/
|
||||||
|
public void rcptTo( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the RSET command.
|
||||||
|
*Cancels the current mail transfer and all current processes,
|
||||||
|
*discards data, and clears all states. Returns to the state that
|
||||||
|
*followed the last method that sent the EHLO command.
|
||||||
|
*Returns a response code and optional response text.
|
||||||
|
* See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#reset
|
||||||
|
* @see #ehlo
|
||||||
|
*/
|
||||||
|
public void reset( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to data sent to the server.
|
||||||
|
*Returns a response code and optional response text.
|
||||||
|
*This method requires using the SMTP_data command to send data,
|
||||||
|
*rather than SMTP_bdat.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#send
|
||||||
|
* @see #data
|
||||||
|
*/
|
||||||
|
public void send( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the extended method.
|
||||||
|
*Along with sendCommandComplete, extends the protocol to
|
||||||
|
*meet client application needs. Sends commands that are not supported
|
||||||
|
*by the Messaging SDK implementation of SMTP.
|
||||||
|
*Can get extended server information, possibly multiline.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseLine Buffer for the response message.
|
||||||
|
* @see SMTPClient#sendCommand
|
||||||
|
* @see #sendCommandComplete
|
||||||
|
*/
|
||||||
|
public void sendCommand( int in_responseCode, StringBuffer in_responseLine );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the extended command.
|
||||||
|
*Along with sendCommand, extends the protocol to meet client application
|
||||||
|
*needs.
|
||||||
|
* @see SMTPClient#sendCommand
|
||||||
|
* @see #sendCommand
|
||||||
|
*/
|
||||||
|
public void sendCommandComplete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the VRFY command.
|
||||||
|
*Returns a response code and optional response text.
|
||||||
|
*For more information, see RFC 821 (URL are listed in SMTP RFCs).
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Buffer for the response message.
|
||||||
|
* @see SMTPClient#verify
|
||||||
|
*/
|
||||||
|
public void verify( int in_responseCode, StringBuffer in_responseMessage );
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
# environment
|
||||||
|
#SHELL = /usr/bin/ksh
|
||||||
|
|
||||||
|
# commands
|
||||||
|
JAVAC = javac
|
||||||
|
ARCH = $(shell uname -s)
|
||||||
|
|
||||||
|
ifeq ($(ARCH), SunOS)
|
||||||
|
ARCH = SOLARIS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ARCH), HP-UX)
|
||||||
|
ARCH = HPUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
# java flags
|
||||||
|
DEBUGJAVAFLAG =
|
||||||
|
OPTJAVAFLAG = -d $(CLASSDIR)
|
||||||
|
JAVAFLAGS = $(OTHERJAVAFLAGS) $(OPTJAVAFLAG) $(DEBUGJAVAFLAG)
|
||||||
|
|
||||||
|
# files and directories
|
||||||
|
CLASSDIR = ../../../built/$(ARCH)/protocol
|
||||||
|
|
||||||
|
#CLASSPATH = .:$(CLASSDIR):$(JDKCLASSPATH)
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
SMTPException.java \
|
||||||
|
SMTPServerException.java \
|
||||||
|
ISMTPSink.java \
|
||||||
|
SMTPSink.java \
|
||||||
|
SMTPClient.java
|
||||||
|
|
||||||
|
OBJS = ${SRCS:.java=.class}
|
||||||
|
|
||||||
|
TARGET = package
|
||||||
|
|
||||||
|
.SUFFIXES: .java .class
|
||||||
|
|
||||||
|
all: $(CLASSDIR) $(TARGET)
|
||||||
|
|
||||||
|
install: $(TARGET)
|
||||||
|
foreach f ( $(OBJS) ) \
|
||||||
|
mv -f $$f $(CLASSDIR)/$$f \
|
||||||
|
end
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CLASSDIR):
|
||||||
|
echo mkdir $(CLASSDIR)
|
||||||
|
- mkdir -p $(CLASSDIR)
|
||||||
|
|
||||||
|
.java.class: $(SRCS)
|
||||||
|
$(JAVAC) $(JAVAFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
echo $(ARCH)
|
||||||
|
rm -f ../../../built/$(ARCH)/netscape/messaging/smtp/*.class
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.smtp;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*The SMTPException class represents an internal error in the SMTP
|
||||||
|
*implementation of the Messaging Access SDK.
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SMTPException extends IOException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*Creates an SMTPException object.
|
||||||
|
*Default constructor for the SMTPException class.
|
||||||
|
*/
|
||||||
|
public SMTPException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Creates an SMTPException object that includes a descriptive string.
|
||||||
|
*@param msg String that describes the exception.
|
||||||
|
*/
|
||||||
|
public SMTPException(String msg)
|
||||||
|
{
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.smtp;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*The SMTPServerException class represents a server response
|
||||||
|
*error in the SMTP implementation of the Messaging Access SDK.
|
||||||
|
*<p>The SMTPServerException class handles server response errors.
|
||||||
|
*An SMTPServerException is thrown only from the error
|
||||||
|
*callback on the response sink. The interface definition for
|
||||||
|
*ISMTPSink states that an SMTPServerException can be thrown,
|
||||||
|
*but it is up to the developer to determine whether or not
|
||||||
|
*the implementation of the error callback will throw this
|
||||||
|
*exception. As a default, the SMTPSink class throws an exception whenever
|
||||||
|
*the error callback is called.
|
||||||
|
*<p>This exception is caused when the server sends an
|
||||||
|
*error saying that some part of the operation failed or is not
|
||||||
|
*supported. This can happen even when all relevant code executes
|
||||||
|
*properly.
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SMTPServerException extends SMTPException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*Creates an SMTPServerException object.
|
||||||
|
*Default constructor for a SMTPServerException object.
|
||||||
|
*/
|
||||||
|
public SMTPServerException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Creates an SMTPServerException object that includes a descriptive string.
|
||||||
|
*@param msg String that describes the exception.
|
||||||
|
*/
|
||||||
|
public SMTPServerException(String msg)
|
||||||
|
{
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,273 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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.smtp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*SMTPSink is the default implementation of the response sink for all
|
||||||
|
*SMTP commands.
|
||||||
|
*<p>The SMTPSink object contains callback methods for each client call.
|
||||||
|
*The client’s processResponses call invokes the appropriate
|
||||||
|
*object method.
|
||||||
|
*<p>The Messaging Access SDK provides the SMTPSink class as a convenience
|
||||||
|
*implementation the ISMTPSink interface.
|
||||||
|
*You can save a step by extending the SMTPSink class, or
|
||||||
|
*you can implement your own class based on the ISMTPSink
|
||||||
|
*interface. The constructor for the SMTPClient class takes an
|
||||||
|
*ISMTPSink interface as a parameter.
|
||||||
|
*<p>These methods return standard SMTP Response Codes, as defined in RFC 821.
|
||||||
|
*See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP"
|
||||||
|
*for more information. For detailed information about SMTP,
|
||||||
|
*see RFC 821. (For the URL, see "Where to Find More Information" in "About This Book.")
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SMTPSink implements ISMTPSink
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*Notification for the response to the BDAT command.
|
||||||
|
*Sends binary data chunks of the specified size to the server.
|
||||||
|
*When using the sendCommand method, send data with the data method
|
||||||
|
*and not with bdat.
|
||||||
|
*Note: bdat is not supported by Messaging Server 4.0. Use data instead.
|
||||||
|
*<p>See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#bdat
|
||||||
|
* @see #data
|
||||||
|
* @see #send
|
||||||
|
*/
|
||||||
|
public void bdat( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the connection to the server.
|
||||||
|
*<P>Connects to the server using the default port.
|
||||||
|
*See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#connect
|
||||||
|
* @see #quit
|
||||||
|
*/
|
||||||
|
public void connect( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the DATA command.
|
||||||
|
*Prepares to send data to the server. The sendCommand method requires
|
||||||
|
*sending data with the data method and not with bdat.
|
||||||
|
*For more information, see RFC 821 (URL: go to SMTP RFCs).
|
||||||
|
*See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#data
|
||||||
|
* @see #bdat
|
||||||
|
* @see #send
|
||||||
|
*/
|
||||||
|
public void data( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the EHLO command.
|
||||||
|
*Along with ehloComplete, returns extended server information.
|
||||||
|
*Can get extended server information (which can be multiline).
|
||||||
|
*See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_serverInfo Extension supported by the server.
|
||||||
|
* @see SMTPClient#ehlo
|
||||||
|
* @see #ehloComplete
|
||||||
|
*/
|
||||||
|
public void ehlo( int in_responseCode, StringBuffer in_serverInfo ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the EHLO command.
|
||||||
|
*Along with ehlo, returns extended server information.
|
||||||
|
* @see SMTPClient#ehlo
|
||||||
|
* @see #ehlo
|
||||||
|
*/
|
||||||
|
public void ehloComplete() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Error notification.
|
||||||
|
*Called when an error occurs.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_errorMessage Text that describes the error.
|
||||||
|
* @exception SMTPServerException If a server response error occurs.
|
||||||
|
* @see SMTPClient#processResponses
|
||||||
|
*/
|
||||||
|
public void error( int in_responseCode, StringBuffer in_errorMessage ) throws SMTPServerException
|
||||||
|
{
|
||||||
|
throw new SMTPServerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the EXPN command.
|
||||||
|
*Along with expandComplete, gets the email address of the specified user.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_user User for whom to get an email address.
|
||||||
|
* @see SMTPClient#expand
|
||||||
|
* @see #expandComplete
|
||||||
|
*/
|
||||||
|
public void expand( int in_responseCode, StringBuffer in_user ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the EXPN command.
|
||||||
|
*Along with expand, gets the email address of the specified user.
|
||||||
|
* @see SMTPClient#expand
|
||||||
|
* @see #expand
|
||||||
|
*/
|
||||||
|
public void expandComplete() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the HELP command.
|
||||||
|
*Along with helpComplete, gets help on the specified topic,
|
||||||
|
*which can be multiline.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_help Line of help text.
|
||||||
|
* @see SMTPClient#help
|
||||||
|
* @see #helpComplete
|
||||||
|
*/
|
||||||
|
public void help( int in_responseCode, StringBuffer in_help ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the HELP command.
|
||||||
|
*Along with help, gets help on a specified topic.
|
||||||
|
* @see SMTPClient#help
|
||||||
|
* @see #help
|
||||||
|
*/
|
||||||
|
public void helpComplete() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the MAIL FROM command.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#mailFrom
|
||||||
|
* @see #rcptTo
|
||||||
|
*/
|
||||||
|
public void mailFrom( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the NOOP command.
|
||||||
|
*<P>The server responds to commands with a "still here" response.
|
||||||
|
*Sending the noop method does nothing except force this response.
|
||||||
|
*Can be used to maintain server connection, perhaps being issued
|
||||||
|
*at timed intervals to make sure that the server is still active.
|
||||||
|
*<p>Resets the autologout timer inside the server.
|
||||||
|
*Not needed by applications that do something and do not maintain the connection.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#noop
|
||||||
|
*/
|
||||||
|
public void noop( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification sink for the response to the QUIT command.
|
||||||
|
*Ends the session. If the session is in the Authentication state,
|
||||||
|
*the server closes the server connection. If the session is in
|
||||||
|
*the Transaction state, the server goes into the Update state
|
||||||
|
*and deletes any marked messages, and then quits.
|
||||||
|
* See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#quit
|
||||||
|
*/
|
||||||
|
public void quit( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the RCPT TO command.
|
||||||
|
*Gets the address of the recipient of the message. Called once for each
|
||||||
|
*recipient; should follow the SMTP_mailFrom function.
|
||||||
|
* See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#rcptTo
|
||||||
|
* @see #mailFrom
|
||||||
|
*/
|
||||||
|
public void rcptTo( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the RSET command.
|
||||||
|
*Cancels the current mail transfer and all current processes,
|
||||||
|
*discards data, and clears all states. Returns to the state that
|
||||||
|
*followed the last method that sent the EHLO command.
|
||||||
|
*Returns a response code and optional response text.
|
||||||
|
* See "SMTP Response Codes" in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#reset
|
||||||
|
* @see #ehlo
|
||||||
|
*/
|
||||||
|
public void reset( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to data sent to the server.
|
||||||
|
*Returns a response code and optional response text.
|
||||||
|
*This method requires using the SMTP_data command to send data,
|
||||||
|
*rather than SMTP_bdat.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Text that describes the 3-digit Response Code.
|
||||||
|
* @see SMTPClient#send
|
||||||
|
* @see #data
|
||||||
|
*/
|
||||||
|
public void send( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to sendCommand() method.
|
||||||
|
*Along with sendCommandComplete, extends the protocol to
|
||||||
|
*meet client application needs. Sends commands that are not supported
|
||||||
|
*by the Messaging SDK implementation of SMTP.
|
||||||
|
*Can get extended server information, possibly multiline.
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseLine Buffer for the response message.
|
||||||
|
* @see SMTPClient#sendCommand
|
||||||
|
* @see #sendCommandComplete
|
||||||
|
*/
|
||||||
|
public void sendCommand( int in_responseCode, StringBuffer in_responseLine ) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the extended command.
|
||||||
|
*Along with sendCommand, extends the protocol to meet client application
|
||||||
|
*needs.
|
||||||
|
* @see SMTPClient#sendCommand
|
||||||
|
* @see #sendCommand
|
||||||
|
*/
|
||||||
|
public void sendCommandComplete() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the VRFY command.
|
||||||
|
*Returns a response code and optional response text.
|
||||||
|
*For more information, see RFC 821 (URL are listed in SMTP RFCs).
|
||||||
|
* See SMTP Response Codes in Chapter 2, "Sending Mail with SMTP."
|
||||||
|
* @param in_responseCode 3-digit Response Code, as defined in RFC 821, for the response.
|
||||||
|
* @param in_responseMessage Buffer for the response message.
|
||||||
|
* @see SMTPClient#verify
|
||||||
|
*/
|
||||||
|
public void verify( int in_responseCode, StringBuffer in_responseMessage ) {}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import netscape.messaging.smtp.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Usage: At the command line type "java SMTPTest serverName domainName sender recipient messageFile"
|
||||||
|
|
||||||
|
class SMTPTest
|
||||||
|
{
|
||||||
|
public static void main( String args[] )
|
||||||
|
{
|
||||||
|
SMTPClient m_client;
|
||||||
|
ISMTPSink m_smtpSink;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create the response sink.
|
||||||
|
m_smtpSink = new SMTPTestSink();
|
||||||
|
|
||||||
|
// Create the SMTP client.
|
||||||
|
m_client = new SMTPClient( m_smtpSink );
|
||||||
|
|
||||||
|
// Set a timeout value of 10 seconds.
|
||||||
|
m_client.setTimeout( 10000 );
|
||||||
|
|
||||||
|
// Set a new chunk size.
|
||||||
|
m_client.setChunkSize( 1048576 );
|
||||||
|
|
||||||
|
// Connect to the specified server.
|
||||||
|
m_client.connect( args[0] );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Send the EHLO command.
|
||||||
|
m_client.ehlo( args[1] );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Specify the sender of the message.
|
||||||
|
m_client.mailFrom( args[2], null );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Specify the recipient of the message.
|
||||||
|
m_client.rcptTo( args[3], null );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Inform the server that data is about to be sent.
|
||||||
|
m_client.data();
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Send the file based message.
|
||||||
|
m_client.send( new FileInputStream( args[4] ) );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Ask for help on helpSend the file based message.
|
||||||
|
m_client.help( "help" );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Perform a noopsk for help on helpSend the file based message.
|
||||||
|
m_client.noop();
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Reset the state of the server.
|
||||||
|
m_client.reset();
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// Send a generic command to the server. In this case it is RSET.
|
||||||
|
m_client.sendCommand( "RSET" );
|
||||||
|
m_client.processResponses();
|
||||||
|
|
||||||
|
// End the SMTP session.
|
||||||
|
m_client.quit();
|
||||||
|
m_client.processResponses();
|
||||||
|
}
|
||||||
|
catch( IOException e )
|
||||||
|
{
|
||||||
|
// Print out the exception.
|
||||||
|
System.out.println( "Exception caught in main:" + e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (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): ______________________________________.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import netscape.messaging.smtp.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification sink for SMTP commands.
|
||||||
|
*@author derekt@netscape.com
|
||||||
|
*@version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SMTPTestSink implements ISMTPSink
|
||||||
|
{
|
||||||
|
Vector m_extendedList;
|
||||||
|
|
||||||
|
SMTPTestSink()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the BDAT command
|
||||||
|
*/
|
||||||
|
public void bdat( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the connection to the server.
|
||||||
|
*/
|
||||||
|
public void connect( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the DATA command.
|
||||||
|
*/
|
||||||
|
public void data( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the EHLO command.
|
||||||
|
*/
|
||||||
|
public void ehlo( int in_responseCode, StringBuffer in_serverInfo )
|
||||||
|
{
|
||||||
|
if ( m_extendedList == null )
|
||||||
|
{
|
||||||
|
m_extendedList = new Vector();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_extendedList.addElement( in_serverInfo.toString() );
|
||||||
|
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_serverInfo.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the EHLO command.
|
||||||
|
*/
|
||||||
|
public void ehloComplete()
|
||||||
|
{
|
||||||
|
System.out.println( "EHLO Complete" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to a server error.
|
||||||
|
*/
|
||||||
|
public void error( int in_responseCode, StringBuffer in_errorMessage ) throws SMTPServerException
|
||||||
|
{
|
||||||
|
throw new SMTPServerException( in_errorMessage.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the EXPN command.
|
||||||
|
*/
|
||||||
|
public void expand( int in_responseCode, StringBuffer in_user )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_user.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the EXPN command.
|
||||||
|
*/
|
||||||
|
public void expandComplete()
|
||||||
|
{
|
||||||
|
System.out.println( "EXPAND Complete" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the HELP command.
|
||||||
|
*/
|
||||||
|
public void help( int in_responseCode, StringBuffer in_help )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_help.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the HELP command.
|
||||||
|
*/
|
||||||
|
public void helpComplete()
|
||||||
|
{
|
||||||
|
System.out.println( "HELP Complete" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the MAIL FROM command.
|
||||||
|
*/
|
||||||
|
public void mailFrom( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the NOOP command.
|
||||||
|
*/
|
||||||
|
public void noop( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification sink for the response to the QUIT command.
|
||||||
|
*/
|
||||||
|
public void quit( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the RCPT TO command.
|
||||||
|
*/
|
||||||
|
public void rcptTo( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the RSET command.
|
||||||
|
*/
|
||||||
|
public void reset( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to data sent to the server.
|
||||||
|
*/
|
||||||
|
public void send( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to sendCommand() method.
|
||||||
|
*/
|
||||||
|
public void sendCommand( int in_responseCode, StringBuffer in_responseLine )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseLine.toString()) );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the completion of the extended command.
|
||||||
|
*/
|
||||||
|
public void sendCommandComplete()
|
||||||
|
{
|
||||||
|
System.out.println( "SENDCOMMAND Complete" );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Notification for the response to the VRFY command.
|
||||||
|
*/
|
||||||
|
public void verify( int in_responseCode, StringBuffer in_responseMessage )
|
||||||
|
{
|
||||||
|
System.out.println( (new Integer(in_responseCode)) + " " + (in_responseMessage.toString()) );
|
||||||
|
};
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче