This commit is contained in:
prasad%netscape.com 1998-08-24 22:22:59 +00:00
Родитель b10d52ff43
Коммит 25e803bf0c
38 изменённых файлов: 15887 добавлений и 0 удалений

Просмотреть файл

@ -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 clients 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 clients 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()) );
};
}