noel 2003/02/08 22:25:35
Modified: src/java/org/apache/james/core Tag: branch_2_1_fcs
MimeMessageWrapper.java
Log:
Consolidate write loops; bypass MimeMessage.writeTo when possible; only call
saveChanges() if the message has been changed
Revision Changes Path
No revision
No revision
1.17.4.2 +108 -63
jakarta-james/src/java/org/apache/james/core/MimeMessageWrapper.java
Index: MimeMessageWrapper.java
===================================================================
RCS file:
/home/cvs/jakarta-james/src/java/org/apache/james/core/MimeMessageWrapper.java,v
retrieving revision 1.17.4.1
retrieving revision 1.17.4.2
diff -u -r1.17.4.1 -r1.17.4.2
--- MimeMessageWrapper.java 4 Feb 2003 19:38:21 -0000 1.17.4.1
+++ MimeMessageWrapper.java 9 Feb 2003 06:25:35 -0000 1.17.4.2
@@ -8,20 +8,40 @@
package org.apache.james.core;
import javax.activation.DataHandler;
-import javax.mail.*;
-import javax.mail.internet.*;
-import java.io.*;
+import javax.mail.Address;
+import javax.mail.Flags;
+import javax.mail.Header;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeUtility;
+import javax.mail.internet.NewsAddress;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.SequenceInputStream;
+import java.io.UnsupportedEncodingException;
import java.text.ParseException;
+import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
-import java.util.Vector;
import org.apache.james.util.InternetPrintWriter;
import org.apache.james.util.RFC2822Headers;
import org.apache.james.util.RFC822DateFormat;
import org.apache.avalon.framework.activity.Disposable;
-
+import org.apache.avalon.excalibur.io.IOUtil;
/**
* This object wraps a MimeMessage, only loading the underlying MimeMessage
@@ -60,7 +80,7 @@
* @param source the MimeMessageSource
*/
public MimeMessageWrapper(MimeMessageSource source) {
- super(javax.mail.Session.getDefaultInstance(System.getProperties(), null));
+ super(Session.getDefaultInstance(System.getProperties(), null));
this.source = source;
}
@@ -86,8 +106,11 @@
}
try {
InputStream in = source.getInputStream();
- headers = new MailHeaders(in);
- in.close();
+ try {
+ headers = new MailHeaders(in);
+ } finally {
+ IOUtil.shutdownStream(in);
+ }
} catch (IOException ioe) {
ioe.printStackTrace();
throw new MessagingException("Unable to parse headers from stream: " +
ioe.getMessage(), ioe);
@@ -105,8 +128,9 @@
//Another thread has already loaded this message
return;
}
+ InputStream in = null;
try {
- InputStream in = source.getInputStream();
+ in = source.getInputStream();
headers = new MailHeaders(in);
ByteArrayInputStream headersIn
@@ -114,10 +138,11 @@
in = new SequenceInputStream(headersIn, in);
message = new MimeMessage(session, in);
- in.close();
} catch (IOException ioe) {
ioe.printStackTrace();
throw new MessagingException("Unable to parse stream: " +
ioe.getMessage(), ioe);
+ } finally {
+ IOUtil.shutdownStream(in);
}
}
@@ -139,11 +164,11 @@
*/
private String getHeaderName(Message.RecipientType recipienttype) throws
MessagingException {
String s;
- if (recipienttype == javax.mail.Message.RecipientType.TO) {
+ if (recipienttype == Message.RecipientType.TO) {
s = RFC2822Headers.TO;
- } else if (recipienttype == javax.mail.Message.RecipientType.CC) {
+ } else if (recipienttype == Message.RecipientType.CC) {
s = RFC2822Headers.CC;
- } else if (recipienttype == javax.mail.Message.RecipientType.BCC) {
+ } else if (recipienttype == Message.RecipientType.BCC) {
s = RFC2822Headers.BCC;
} else if (recipienttype == RecipientType.NEWSGROUPS) {
s = "Newsgroups";
@@ -168,21 +193,16 @@
*/
public void writeTo(OutputStream os) throws IOException, MessagingException {
if (message == null || !isModified()) {
- //We do not want to instantiate the message... just read from source
- // and write to this outputstream
-
- // TODO: This is really a bad way to do this sort of thing. A shared
buffer to
- // allow simultaneous read/writes would be a substantial
improvement
- byte[] block = new byte[1024];
- int read = 0;
+ // We do not want to instantiate the message... just read from source
+ // and write to this outputstream
InputStream in = source.getInputStream();
- while ((read = in.read(block)) > 0) {
- os.write(block, 0, read);
+ try {
+ copyStream(in, os);
+ } finally {
+ IOUtil.shutdownStream(in);
}
- in.close();
} else {
- message.saveChanges();
- message.writeTo(os);
+ writeTo(os, os);
}
}
@@ -207,21 +227,19 @@
//First handle the headers
InputStream in = source.getInputStream();
- InternetHeaders headers = new InternetHeaders(in);
- PrintWriter pos = new InternetPrintWriter(new BufferedWriter(new
OutputStreamWriter(headerOs), 512), true);
- for (Enumeration e = headers.getNonMatchingHeaderLines(ignoreList);
e.hasMoreElements(); ) {
- String header = (String)e.nextElement();
- pos.println(header);
- }
- pos.println();
- // TODO: This is really a bad way to do this sort of thing. A shared
buffer to
- // allow simultaneous read/writes would be a substantial
improvement
- byte[] block = new byte[1024];
- int read = 0;
- while ((read = in.read(block)) > 0) {
- bodyOs.write(block, 0, read);
+ try {
+ InternetHeaders headers = new InternetHeaders(in);
+ PrintWriter pos = new InternetPrintWriter(new BufferedWriter(new
OutputStreamWriter(headerOs), 512), true);
+ for (Enumeration e = headers.getNonMatchingHeaderLines(ignoreList);
e.hasMoreElements(); ) {
+ String header = (String)e.nextElement();
+ pos.println(header);
+ }
+ pos.println();
+ pos.flush();
+ copyStream(in, bodyOs);
+ } finally {
+ IOUtil.shutdownStream(in);
}
- in.close();
} else {
writeTo(message, headerOs, bodyOs, ignoreList);
}
@@ -244,32 +262,48 @@
MimeMessageWrapper wrapper = (MimeMessageWrapper)message;
wrapper.writeTo(headerOs, bodyOs, ignoreList);
} else {
- message.saveChanges();
+ if (modified) {
+ saveChanges();
+ }
//Write the headers (minus ignored ones)
Enumeration headers = message.getNonMatchingHeaderLines(ignoreList);
- PrintWriter pos = new InternetPrintWriter(new BufferedWriter(new
OutputStreamWriter(headerOs), 512), true);
+ PrintWriter hos = new InternetPrintWriter(new BufferedWriter(new
OutputStreamWriter(headerOs), 512), true);
while (headers.hasMoreElements()) {
- pos.println((String)headers.nextElement());
+ hos.println((String)headers.nextElement());
}
+ // Print header/data separator
+ hos.println();
+ hos.flush();
+
+ InputStream bis = null;
+ OutputStream bos = null;
+ // Write the raw body to the output stream
+ try {
+ bis = message.getRawInputStream();
+ bos = bodyOs;
+ } catch(javax.mail.MessagingException me) {
+ // we may get a "No content" exception
+ // if that happens, try it the hard way
+
+ // Why, you ask? In JavaMail v1.3, when you initially
+ // create a message using MimeMessage APIs, there is no
+ // raw content available. getInputStream() works, but
+ // getRawInputStream() throws an exception.
- //Write the message without any headers
-
- //Get a list of all headers
- Vector headerNames = new Vector();
- Enumeration allHeaders = message.getAllHeaders();
- while (allHeaders.hasMoreElements()) {
- Header header = (Header)allHeaders.nextElement();
- headerNames.add(header.getName());
+ bos = MimeUtility.encode(bodyOs, message.getEncoding());
+ bis = message.getInputStream();
}
- String headerNamesArray[] = (String[])headerNames.toArray(new
String[0]);
- //Write message to bodyOs, ignoring all headers (without writing any
headers)
- message.writeTo(bodyOs, headerNamesArray);
+ try {
+ copyStream(bis, bos);
+ }
+ finally {
+ IOUtil.shutdownStream(bis);
+ }
}
}
-
/**
* Various reader methods
*/
@@ -422,15 +456,16 @@
try {
LineNumberReader counter = new LineNumberReader(new
InputStreamReader(in, getEncoding()));
//Read through all the data
- char[] block = new char[1024];
+ char[] block = new char[4096];
while (counter.read(block) > -1) {
//Just keep reading
}
- in.close();
return counter.getLineNumber();
} catch (IOException ioe) {
ioe.printStackTrace();
return -1;
+ } finally {
+ IOUtil.shutdownStream(in);
}
}
@@ -630,14 +665,25 @@
loadMessage();
}
InputStream in = getContentStream();
+ try {
+ copyStream(in, outs);
+ } finally {
+ IOUtil.shutdownStream(in);
+ }
+ }
+
+ /**
+ * Convenience method to copy streams
+ */
+ private static void copyStream(InputStream in, OutputStream out) throws
IOException {
// TODO: This is really a bad way to do this sort of thing. A shared
buffer to
// allow simultaneous read/writes would be a substantial improvement
- byte block[] = new byte[1024];
- int len = 0;
- while ((len = in.read(block)) > -1) {
- outs.write(block, 0, len);
+ byte[] block = new byte[1024];
+ int read = 0;
+ while ((read = in.read(block)) > -1) {
+ out.write(block, 0, read);
}
- in.close();
+ out.flush();
}
/*
@@ -874,8 +920,8 @@
if (message == null) {
loadMessage();
}
- modified = true;
message.saveChanges();
+ modified = false;
}
/*
@@ -912,5 +958,4 @@
((Disposable)source).dispose();
}
}
-
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]