You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/07/09 21:04:39 UTC

svn commit: r675310 - in /james/mime4j/trunk/src: main/java/org/apache/james/mime4j/ main/java/org/apache/james/mime4j/decoder/ main/java/org/apache/james/mime4j/message/ main/java/org/apache/james/mime4j/util/ test/java/org/apache/james/mime4j/

Author: rdonkin
Date: Wed Jul  9 12:04:37 2008
New Revision: 675310

URL: http://svn.apache.org/viewvc?rev=675310&view=rev
Log:
MIME4J-5 Performance improvements patch 4, https://issues.apache.org/jira/browse/MIME4J-5. Contributed by Oleg Kalnichevski. Fixes issue caused by reset when parsing complex messages with embedded mail. Other minor performance improvements.

Modified:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractEntity.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BasicBufferingInputStream.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStream.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStreamAdaptor.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeBoundaryInputStream.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeEntity.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/decoder/DecoderUtil.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
    james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenEmbeddedMessageTest.java

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractEntity.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractEntity.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractEntity.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractEntity.java Wed Jul  9 12:04:37 2008
@@ -212,6 +212,7 @@
         case EntityStates.T_START_MULTIPART:
         case EntityStates.T_PREAMBLE:
         case EntityStates.T_EPILOGUE:
+        case EntityStates.T_END_OF_STREAM:
             return body;
         default:
             throw new IllegalStateException("Invalid state :" + stateToString(state));
@@ -322,7 +323,8 @@
     }
 
     public String toString() {
-        return "Current state: " + stateToString(state);
+        return getClass().getSimpleName() + " [" + stateToString(state)
+        + "][" + body.getMimeType() + "][" + body.getBoundary() + "]";
     }
 
     /**

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BasicBufferingInputStream.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BasicBufferingInputStream.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BasicBufferingInputStream.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BasicBufferingInputStream.java Wed Jul  9 12:04:37 2008
@@ -85,5 +85,8 @@
             return total;
         }
     }
+    
+    public void reset() {
+    }
 
 }

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStream.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStream.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStream.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStream.java Wed Jul  9 12:04:37 2008
@@ -38,4 +38,9 @@
      */
     public abstract int readLine(final ByteArrayBuffer dst) throws IOException;
     
+    /**
+     * Resets the internal state.
+     */
+    public abstract void reset();
+    
 }

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStreamAdaptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStreamAdaptor.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStreamAdaptor.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/BufferingInputStreamAdaptor.java Wed Jul  9 12:04:37 2008
@@ -97,4 +97,10 @@
         return this.used;
     }
 
+    public void reset() {
+        if (this.bis != null) {
+            this.bis.reset();
+        }
+    }
+    
 }

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeBoundaryInputStream.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeBoundaryInputStream.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeBoundaryInputStream.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeBoundaryInputStream.java Wed Jul  9 12:04:37 2008
@@ -49,7 +49,7 @@
             throws IOException {
         this.buffer = inbuffer;
         this.eof = false;
-        this.limit = 0;
+        this.limit = -1;
         this.atBoundary = false;
         this.boundaryLen = 0;
         this.lastPart = false;
@@ -121,6 +121,14 @@
         return buffer.read(b, off, chunk);
     }
 
+    /**
+     * Resets the internal state. This will force the boundary to be rescanned.
+     */
+    public void reset() {
+        atBoundary = false;
+        limit = -1;
+    }
+    
     public int readLine(final ByteArrayBuffer dst) throws IOException {
         if (dst == null) {
             throw new IllegalArgumentException("Destination buffer may not be null");

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeEntity.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeEntity.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeEntity.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeEntity.java Wed Jul  9 12:04:37 2008
@@ -27,6 +27,8 @@
     private BufferingInputStreamAdaptor dataStream;
     private boolean skipHeader;
     
+    private byte[] tmpbuf;
+    
     public MimeEntity(
             RootInputStream rootStream,
             InputStream rawStream,
@@ -164,6 +166,11 @@
     private void createMimeStream() throws IOException {
         mimeStream = new MimeBoundaryInputStream(inbuffer, body.getBoundary());
         dataStream = new BufferingInputStreamAdaptor(mimeStream); 
+        // If multipart message is embedded into another multipart message
+        // make sure to reset parent's mime stream
+        if (rawStream instanceof BufferingInputStream) {
+            ((BufferingInputStream) rawStream).reset();
+        }
     }
     
     private void clearMimeStream() {
@@ -173,8 +180,10 @@
     
     private void advanceToBoundary() throws IOException {
         if (!dataStream.eof()) {
-            byte[] tmp = new byte[2048];
-            while (dataStream.read(tmp)!= -1) {
+            if (tmpbuf == null) {
+                tmpbuf = new byte[2048];
+            }
+            while (dataStream.read(tmpbuf)!= -1) {
             }
         }
     }

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java Wed Jul  9 12:04:37 2008
@@ -64,11 +64,6 @@
  *          }
  *      }
  * </pre>
- * <p>
- * <strong>NOTE:</strong> All lines must end with CRLF 
- * (<code>\r\n</code>). If you are unsure of the line endings in your stream 
- * you should wrap it in a {@link org.apache.james.mime4j.EOLConvertingInputStream}
- * instance.</p>
  * <p>Instances of {@link MimeTokenStream} are reusable: Invoking the
  * method {@link #parse(InputStream)} resets the token streams internal
  * state. However, they are definitely <em>not</em> thread safe. If you

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/decoder/DecoderUtil.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/decoder/DecoderUtil.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/decoder/DecoderUtil.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/decoder/DecoderUtil.java Wed Jul  9 12:04:37 2008
@@ -26,6 +26,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.CharArrayBuffer;
 import org.apache.james.mime4j.util.CharsetUtil;
 
 /**
@@ -127,7 +128,7 @@
         /*
          * Replace _ with =20
          */
-        StringBuffer sb = new StringBuffer();
+        CharArrayBuffer sb = new CharArrayBuffer(128);
         for (int i = 0; i < encodedWord.length(); i++) {
             char c = encodedWord.charAt(i);
             if (c == '_') {
@@ -150,7 +151,7 @@
      * @return the decoded string.
      */
     public static String decodeEncodedWords(String body) {
-        StringBuffer sb = new StringBuffer();
+        CharArrayBuffer sb = new CharArrayBuffer(128);
         
         int p1 = 0;
         int p2 = 0;

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java Wed Jul  9 12:04:37 2008
@@ -32,6 +32,7 @@
 import java.util.List;
 
 import org.apache.james.mime4j.AbstractContentHandler;
+import org.apache.james.mime4j.CharArrayBuffer;
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.MimeStreamParser;
 import org.apache.james.mime4j.field.ContentTypeField;
@@ -146,7 +147,7 @@
      * @return headers
      */
     public String toString() {
-        StringBuffer str = new StringBuffer();
+        CharArrayBuffer str = new CharArrayBuffer(128);
         for (Iterator it = fields.iterator(); it.hasNext();) {
             str.append(it.next().toString());
             str.append("\r\n");

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java Wed Jul  9 12:04:37 2008
@@ -25,6 +25,7 @@
 import java.util.Stack;
 
 import org.apache.james.mime4j.BodyDescriptor;
+import org.apache.james.mime4j.CharArrayBuffer;
 import org.apache.james.mime4j.ContentHandler;
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.MimeStreamParser;
@@ -222,7 +223,7 @@
          */
         public void epilogue(InputStream is) throws IOException {
             expect(Multipart.class);
-            StringBuffer sb = new StringBuffer();
+            CharArrayBuffer sb = new CharArrayBuffer(128);
             int b;
             while ((b = is.read()) != -1) {
                 sb.append((char) b);
@@ -235,7 +236,7 @@
          */
         public void preamble(InputStream is) throws IOException {
             expect(Multipart.class);
-            StringBuffer sb = new StringBuffer();
+            CharArrayBuffer sb = new CharArrayBuffer(128);
             int b;
             while ((b = is.read()) != -1) {
                 sb.append((char) b);

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MimeUtil.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MimeUtil.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MimeUtil.java Wed Jul  9 12:04:37 2008
@@ -25,6 +25,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.james.mime4j.BodyDescriptor;
+import org.apache.james.mime4j.CharArrayBuffer;
 
 
 /**
@@ -167,7 +168,7 @@
         /*
          * Unfold Content-Type value
          */
-        StringBuffer sb = new StringBuffer();
+        CharArrayBuffer sb = new CharArrayBuffer(128);
         for (int i = 0; i < pValue.length(); i++) {
             char c = pValue.charAt(i);
             if (c == '\r' || c == '\n') {
@@ -193,8 +194,8 @@
         result.put("", main);
         if (rest != null) {
             char[] chars = rest.toCharArray();
-            StringBuffer paramName = new StringBuffer();
-            StringBuffer paramValue = new StringBuffer();
+            CharArrayBuffer paramName = new CharArrayBuffer(64);
+            CharArrayBuffer paramValue = new CharArrayBuffer(64);
 
             final byte READY_FOR_NAME = 0;
             final byte IN_NAME = 1;
@@ -222,8 +223,8 @@
                             break;
                         }
 
-                        paramName = new StringBuffer();
-                        paramValue = new StringBuffer();
+                        paramName = new CharArrayBuffer(64);
+                        paramValue = new CharArrayBuffer(64);
 
                         state = IN_NAME;
                         // fall-through

Modified: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenEmbeddedMessageTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenEmbeddedMessageTest.java?rev=675310&r1=675309&r2=675310&view=diff
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenEmbeddedMessageTest.java (original)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenEmbeddedMessageTest.java Wed Jul  9 12:04:37 2008
@@ -21,7 +21,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.nio.charset.Charset;
 
 import junit.framework.TestCase;
 
@@ -40,7 +39,7 @@
         super.tearDown();
     }
 
-    public void _testWhenRecurseShouldVisitInnerMailsAndInnerMultiparts() throws Exception {
+    public void testWhenRecurseShouldVisitInnerMailsAndInnerMultiparts() throws Exception {
         stream.setRecursionMode(MimeTokenStream.M_RECURSE);
 
         nextIs(MimeTokenStream.T_START_HEADER);
@@ -113,11 +112,14 @@
         nextIs(MimeTokenStream.T_START_HEADER);
         nextIs(MimeTokenStream.T_FIELD);
         nextIs(MimeTokenStream.T_END_HEADER);
-        nextIs(MimeTokenStream.T_BODY);
+        nextIs(MimeTokenStream.T_START_MULTIPART);
         checkInputStream(ExampleMail.MIME_MULTIPART_EMBEDDED_MESSAGES_INNER_MULTIPART_MIXED);
+        nextIs(MimeTokenStream.T_END_MULTIPART);
         nextIs(MimeTokenStream.T_END_BODYPART);
         nextIs(MimeTokenStream.T_EPILOGUE);
         nextIs(MimeTokenStream.T_END_MULTIPART);
+        nextIs(MimeTokenStream.T_END_MESSAGE);
+        nextIs(MimeTokenStream.T_END_OF_STREAM);
     }
     
     



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org