Author: rdonkin
Date: Wed Feb 20 10:37:05 2008
New Revision: 629567

URL: http://svn.apache.org/viewvc?rev=629567&view=rev
Log:
Allow getInputStream for the contents of a multipart message. This allows more 
efficient then reading of data.

Added:
    
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MultipartStreamTest.java
Modified:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/Cursor.java
    
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/StreamCursor.java

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/Cursor.java
URL: 
http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/Cursor.java?rev=629567&r1=629566&r2=629567&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/Cursor.java 
(original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/Cursor.java Wed 
Feb 20 10:37:05 2008
@@ -97,7 +97,7 @@
      * Advances the cursor.
      * @return the next byte
      * @throws IOException
-     * @see #getStream()
+     * @see #nextSection()
      */
     public byte advance() throws IOException;
     
@@ -105,6 +105,11 @@
      * Gets a stream to read the contents of the next section of the message.
      * @return <code>InputStream</code>, not null
      */
-    public InputStream getStream();
+    public InputStream nextSection();
 
+    /**
+     * Gets a stream to read the contents of the rest of this message.
+     * @return <code>InputStream</code>, not null
+     */
+    public InputStream rest();
 }

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=629567&r1=629566&r2=629567&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 Feb 20 10:37:05 2008
@@ -302,6 +302,7 @@
     abstract static class StateMachine {
         int state;
         abstract int next() throws IOException, MimeException;
+        abstract InputStream read();
     }
 
     private static class RawEntity extends StateMachine {
@@ -314,6 +315,9 @@
             state = T_END_OF_STREAM;
             return state;
         }
+        InputStream read() {
+            return stream;
+        }
     }
 
     private abstract class Entity extends StateMachine {
@@ -348,7 +352,7 @@
                     cursor.boundary(boundary);
                    
                     if (isRaw()) {
-                        currentStateMachine = new 
RawEntity(cursor.getStream());
+                        currentStateMachine = new 
RawEntity(cursor.nextSection());
                     } else {
                         currentStateMachine = new 
BodyPart(cursor.nextMimePartCursor(), body);
                     }
@@ -397,7 +401,11 @@
                     break;
                 case T_START_MULTIPART:
                     cursor.boundary(body.getBoundary());
-                    state = T_PREAMBLE;
+                    if (cursor.isEnded()) {
+                        state = T_END_MULTIPART;
+                    } else {
+                        state = T_PREAMBLE;
+                    }
                     break;
                 case T_PREAMBLE:
                     return setParseBodyPartState();
@@ -421,6 +429,19 @@
             return state;
         }
 
+        InputStream read() {
+            switch (getState()) {
+                case T_PREAMBLE:
+                case T_EPILOGUE:
+                case T_BODY:
+                    return cursor.nextSection();
+                case T_START_MULTIPART:
+                    return cursor.rest();
+                default:
+                    throw new IllegalStateException("Expected state to be 
either of T_RAW_ENTITY, T_PREAMBLE, or T_EPILOGUE.");
+            }
+        }
+        
         private void initHeaderParsing() throws IOException, MimeException {
             body = newBodyDescriptor(parent);
             startLineNumber = lineNumber = cursor.getLineNumber();
@@ -544,7 +565,7 @@
     private int parseMessage(Cursor cursor, BodyDescriptor parent) {
         switch (recursionMode) {
             case M_RAW:
-                currentStateMachine = new RawEntity(cursor.getStream());
+                currentStateMachine = new RawEntity(cursor.nextSection());
                 break;
             case M_NO_RECURSE:
                 // expected to be called only at start of paring
@@ -753,16 +774,7 @@
      *   invalid value.
      */
     public InputStream getInputStream() {
-        switch (getState()) {
-            case T_RAW_ENTITY:
-                return ((RawEntity) currentStateMachine).stream;
-            case T_PREAMBLE:
-            case T_EPILOGUE:
-            case T_BODY:
-                return ((Entity) currentStateMachine).cursor.getStream();
-            default:
-                throw new IllegalStateException("Expected state to be either 
of T_RAW_ENTITY, T_PREAMBLE, or T_EPILOGUE.");
-        }
+        return currentStateMachine.read();
     }
 
     /**

Modified: 
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/StreamCursor.java
URL: 
http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/StreamCursor.java?rev=629567&r1=629566&r2=629567&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/StreamCursor.java 
(original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/StreamCursor.java 
Wed Feb 20 10:37:05 2008
@@ -132,9 +132,9 @@
     }
 
     /**
-     * @see Cursor#getStream()
+     * @see Cursor#nextSection()
      */
-    public InputStream getStream() {
+    public InputStream nextSection() {
         InputStream result = stream;
         if (result == null)
         {
@@ -147,6 +147,12 @@
      * @see Cursor#advance()
      */
     public byte advance() throws IOException {
-        return (byte) getStream().read();
+        return (byte) nextSection().read();
     }
+
+    public InputStream rest() {
+        return contents;
+    }
+    
+    
 }

Added: 
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MultipartStreamTest.java
URL: 
http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MultipartStreamTest.java?rev=629567&view=auto
==============================================================================
--- 
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MultipartStreamTest.java
 (added)
+++ 
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MultipartStreamTest.java
 Wed Feb 20 10:37:05 2008
@@ -0,0 +1,126 @@
+package org.apache.james.mime4j;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.commons.io.IOUtils;
+
+import junit.framework.TestCase;
+
+public class MultipartStreamTest extends TestCase {
+
+    private static final Charset US_ASCII = Charset.forName("us-ascii");
+    
+    private static final String BODY = "A Preamble\r\n" +
+                "--1729\r\n\r\n" +
+                "Simple plain text\r\n" +
+                "--1729\r\n" +
+                "Content-Type: text/plain; charset=US-ASCII\r\n\r\n" +
+                "Some more text\r\n" +
+                "--1729--\r\n";
+    public static final String MESSAGE = "To: Road Runner <[EMAIL 
PROTECTED]>\r\n" +
+            "From: Wile E. Cayote <[EMAIL PROTECTED]>\r\n" +
+            "Date: Tue, 12 Feb 2008 17:34:09 +0000 (GMT)\r\n" +
+            "Subject: Mail\r\n" +
+            "Content-Type: multipart/mixed;boundary=1729\r\n\r\n" +
+            BODY;
+    
+    public static final String COMPLEX_MESSAGE = "To: Wile E. Cayote <[EMAIL 
PROTECTED]>\r\n" +
+    "From: Road Runner <[EMAIL PROTECTED]>\r\n" +
+    "Date: Tue, 19 Feb 2008 17:34:09 +0000 (GMT)\r\n" +
+    "Subject: Mail\r\n" +
+    "Content-Type: multipart/mixed;boundary=42\r\n\r\n" +
+    "A little preamble\r\n" +
+    "--42\r\n" +
+    "Content-Type: text/plain; charset=US-ASCII\r\n\r\n" +
+    "Rhubard!\r\n" +
+    "--42\r\n" +
+    "Content-Type: message/rfc822\r\n\r\n" +
+    MESSAGE +
+    "\r\n" +
+    "--42\r\n" +
+    "Content-Type: text/plain; charset=US-ASCII\r\n\r\n" +
+    "Custard!" +
+    "\r\n" +
+    "--42--\r\n";
+    
+    MimeTokenStream parser;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        parser = new MimeTokenStream();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+    
+    public void testShouldSupplyInputStreamForSimpleBody() throws Exception {
+        parser.parse(new 
ByteArrayInputStream(US_ASCII.encode(MESSAGE).array()));
+        checkState(MimeTokenStream.T_START_HEADER);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_END_HEADER);
+        checkState(MimeTokenStream.T_START_MULTIPART);
+        InputStream out = parser.getInputStream();
+        assertEquals(BODY, IOUtils.toString(out, "us-ascii"));
+        checkState(MimeTokenStream.T_END_MULTIPART);
+    }
+    
+    public void testInputStreamShouldReadOnlyMessage() throws Exception {
+        parser.parse(new 
ByteArrayInputStream(US_ASCII.encode(COMPLEX_MESSAGE).array()));
+        checkState(MimeTokenStream.T_START_HEADER);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_END_HEADER);
+        checkState(MimeTokenStream.T_START_MULTIPART);
+        checkState(MimeTokenStream.T_PREAMBLE);
+        checkState(MimeTokenStream.T_START_BODYPART);
+        checkState(MimeTokenStream.T_START_HEADER);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_END_HEADER);
+        checkState(MimeTokenStream.T_BODY);
+        checkState(MimeTokenStream.T_END_BODYPART);
+        checkState(MimeTokenStream.T_START_BODYPART);
+        checkState(MimeTokenStream.T_START_HEADER);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_END_HEADER);
+        checkState(MimeTokenStream.T_START_MESSAGE);
+        checkState(MimeTokenStream.T_START_HEADER);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_END_HEADER);
+        checkState(MimeTokenStream.T_START_MULTIPART);
+        InputStream out = parser.getInputStream();
+        assertEquals(BODY, IOUtils.toString(out, "us-ascii"));
+        checkState(MimeTokenStream.T_END_MULTIPART);
+        checkState(MimeTokenStream.T_END_MESSAGE);
+        //TODO: 
+        //checkState(MimeTokenStream.T_END_BODYPART);
+        checkState(MimeTokenStream.T_START_BODYPART);
+        checkState(MimeTokenStream.T_START_HEADER);
+        checkState(MimeTokenStream.T_FIELD);
+        checkState(MimeTokenStream.T_END_HEADER);
+        checkState(MimeTokenStream.T_BODY);
+        checkState(MimeTokenStream.T_END_BODYPART);
+        checkState(MimeTokenStream.T_EPILOGUE);
+        checkState(MimeTokenStream.T_END_MULTIPART);
+        checkState(MimeTokenStream.T_END_MESSAGE);
+        checkState(MimeTokenStream.T_END_OF_STREAM);
+    }
+
+    private void checkState(final int state) throws IOException, MimeException 
{
+        assertEquals(MimeTokenStream.stateToString(state), 
MimeTokenStream.stateToString(parser.next()));
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to