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/26 19:14:42 UTC

svn commit: r680015 - in /james/server/trunk: experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/ experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/ imap-codec-library/src/...

Author: rdonkin
Date: Sat Jul 26 10:14:41 2008
New Revision: 680015

URL: http://svn.apache.org/viewvc?rev=680015&view=rev
Log:
Support for BODYSTRUCTURE for multipart messages

Modified:
    james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/AbstractTestFetchBodyStructure.java
    james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/FetchMultipartBodyStructure.test
    james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java
    james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java
    james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalHostSystem.java
    james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java
    james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java
    james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java

Modified: james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/AbstractTestFetchBodyStructure.java
URL: http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/AbstractTestFetchBodyStructure.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/AbstractTestFetchBodyStructure.java (original)
+++ james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/AbstractTestFetchBodyStructure.java Sat Jul 26 10:14:41 2008
@@ -30,12 +30,24 @@
     public void testFetchFetchSimpleBodyStructureUS() throws Exception {
         scriptTest("FetchSimpleBodyStructure", Locale.US);
     }
-    
+
     public void testFetchFetchSimpleBodyStructureKOREA() throws Exception {
         scriptTest("FetchSimpleBodyStructure", Locale.KOREA);
     }
-    
+
     public void testFetchFetchSimpleBodyStructureITALY() throws Exception {
         scriptTest("FetchSimpleBodyStructure", Locale.ITALY);
     }
+
+    public void testFetchFetchMultipartBodyStructureUS() throws Exception {
+        scriptTest("FetchMultipartBodyStructure", Locale.US);
+    }
+
+    public void testFetchFetchMultipartBodyStructureKOREA() throws Exception {
+        scriptTest("FetchMultipartBodyStructure", Locale.KOREA);
+    }
+
+    public void testFetchFetchMultipartBodyStructureITALY() throws Exception {
+        scriptTest("FetchMultipartBodyStructure", Locale.ITALY);
+    }
 }

Modified: james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/FetchMultipartBodyStructure.test
URL: http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/FetchMultipartBodyStructure.test?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/FetchMultipartBodyStructure.test (original)
+++ james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/FetchMultipartBodyStructure.test Sat Jul 26 10:14:41 2008
@@ -7,8 +7,7 @@
 S: \* OK \[UIDVALIDITY \d+\]
 S: \* OK \[PERMANENTFLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\Seen\)\]
 S: A3 OK \[READ-WRITE\] SELECT completed\.
-C: A4 APPEND testmailbox {8994+}
-C:  
+C: A4 APPEND testmailbox {8989+}
 C: Return-Path: <ro...@blueyonder.co.uk>
 C: Received: (qmail 18554 invoked from network); 25 May 2008 14:38:53 -0000
 C: Received: from unknown (HELO p3presmtp01-16.prod.phx3.secureserver.net)
@@ -49,7 +48,7 @@
 C: Subject: This is an example of a multipart mixed email with image content
 C: From: Robert Burrell Donkin <ro...@blueyonder.co.uk>
 C: To: Robert Burrell Donkin <rd...@apache.org>
-C: Content-Type: multipart/mixed; boundary=\"=-tIdGYVstQJghyEDATnJ+\"
+C: Content-Type: multipart/mixed; boundary="=-tIdGYVstQJghyEDATnJ+"
 C: Content-Location: http://www.example.org/
 C: Date: Sun, 25 May 2008 15:38:13 +0100
 C: Message-Id: <12...@localhost>
@@ -209,8 +208,7 @@
 S: \* 2 FETCH \(\)
 S: A6 OK FETCH completed\.
 C: A7 FETCH 1 (BODY[])
-S: \* 1 FETCH \(FLAGS \(\\Recent \\Seen\) BODY\[\] \{8994\}
-S:  
+S: \* 1 FETCH \(FLAGS \(\\Recent \\Seen\) BODY\[\] \{8989\}
 S: Return-Path: <robertburrelldonkin@blueyonder\.co\.uk>
 S: Received: \(qmail 18554 invoked from network\); 25 May 2008 14:38:53 -0000
 S: Received: from unknown \(HELO p3presmtp01-16\.prod\.phx3\.secureserver\.net\)
@@ -251,7 +249,7 @@
 S: Subject: This is an example of a multipart mixed email with image content
 S: From: Robert Burrell Donkin <robertburrelldonkin@blueyonder\.co\.uk>
 S: To: Robert Burrell Donkin <rdonkin@apache\.org>
-S: Content-Type: multipart/mixed; boundary=\\"=-tIdGYVstQJghyEDATnJ\+\\"
+S: Content-Type: multipart/mixed; boundary="=-tIdGYVstQJghyEDATnJ\+"
 S: Content-Location: http://www\.example\.org/
 S: Date: Sun, 25 May 2008 15:38:13 \+0100
 S: Message-Id: <12...@localhost>
@@ -485,8 +483,7 @@
 S: --=-tIdGYVstQJghyEDATnJ\+--\)
 S: A8 OK FETCH completed\.
 C: A9 FETCH 1 (BODY[HEADER])
-S: \* 1 FETCH \(BODY\[HEADER\] \{2867\}
-S:  
+S: \* 1 FETCH \(BODY\[HEADER\] \{2862\}
 S: Return-Path: <robertburrelldonkin@blueyonder\.co\.uk>
 S: Received: \(qmail 18554 invoked from network\); 25 May 2008 14:38:53 -0000
 S: Received: from unknown \(HELO p3presmtp01-16\.prod\.phx3\.secureserver\.net\)
@@ -527,7 +524,7 @@
 S: Subject: This is an example of a multipart mixed email with image content
 S: From: Robert Burrell Donkin <robertburrelldonkin@blueyonder\.co\.uk>
 S: To: Robert Burrell Donkin <rdonkin@apache\.org>
-S: Content-Type: multipart/mixed; boundary=\\"=-tIdGYVstQJghyEDATnJ\+\\"
+S: Content-Type: multipart/mixed; boundary="=-tIdGYVstQJghyEDATnJ\+"
 S: Content-Location: http://www\.example\.org/
 S: Date: Sun, 25 May 2008 15:38:13 \+0100
 S: Message-Id: <12...@localhost>
@@ -594,19 +591,12 @@
 S: \)
 S: A14 OK FETCH completed\.
 C: A15 FETCH 1 (BODY[3.1])
-S: \* 1 FETCH \(BODY\[3\.1\] \{492\}
-S: iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAL
-S: EwAACxMBAJqcGAAAAAd0SU1FB9gFGQ4iJ99ufcYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRo
-S: IEdJTVBXgQ4XAAAA0ElEQVQY02XMwUrDQBhF4XsnkyYhjWJaCloEN77/a/gERVwJLQiiNjYmbTqZ
-S: /7qIG/VsPziMTw\+23Wj/ovZdMQJgViCvWNVusfa23djuUf2nugbnI2RynkWF5a2Fwdvrs7q9vhqE
-S: E2QAEIO6BhZBerUf6luMw49NyTR0OLw5kJD9sqk4Ipwc6GAREv5n5piXTDOQfy1JMSs8ZgXKq2kF
-S: iwDgEriEecnLlefFEmGAIvqD4ggJJNMM85qLtXfX9xYGuEQ\+4/kIi0g88zlXd66\+\+QaQDG5GPZyp
-S: rQAAAABJRU5ErkJggg==
-S: 
+S: \* 1 FETCH \(BODY\[3\.1\] \{0\}
 S: \)
 S: A15 OK FETCH completed\.
 C: A16 FETCH 1 (BODY[3.2])
-S: \* 1 FETCH \(BODY\[3\.2\] NIL\)
+S: \* 1 FETCH \(BODY\[3\.2\] \{0\}
+S: \)
 S: A16 OK FETCH completed\.
 C: A17 FETCH 1 (BODY[4])
 S: \* 1 FETCH \(BODY\[4\] \{3193\}
@@ -654,86 +644,44 @@
 S: \)
 S: A17 OK FETCH completed\.
 C: A18 FETCH 1 (BODY[4.1])
-S: \* 1 FETCH \(BODY\[4\.1\] \{3193\}
-S: Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=
-S: barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=
-S: b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=
-S: hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=
-S: arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=
-S:  Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=
-S: ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=
-S: rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =
-S: Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=
-S: barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=
-S: b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=
-S: hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=
-S: arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=
-S:  Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=
-S: ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=
-S: rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =
-S: Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=
-S: barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=
-S: b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=
-S: hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=
-S: arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=
-S:  Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=
-S: ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=
-S: rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =
-S: Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=
-S: barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=
-S: b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=
-S: hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=
-S: arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=
-S:  Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=
-S: ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=
-S: rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =
-S: Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=
-S: barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=
-S: b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=
-S: hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=
-S: arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=
-S:  Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=
-S: ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=
-S: rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =
-S: Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb
+S: \* 1 FETCH \(BODY\[4\.1\] \{0\}
 S: \)
 S: A18 OK FETCH completed\.
 C: A19 FETCH 1 (BODY[4.1.MIME])
-S: \* 1 FETCH \(BODY\[4\.1\.MIME\] \{354\}
-S: Content-Disposition: attachment; filename=rhubarb\.txt
-S: Content-Type: text/plain; name=rhubarb\.txt; charset=us-ascii
-S: Content-Language: en, en-US, en-CA, en-AU
-S: Content-Transfer-Encoding: quoted-printable
-S: Content-Location: "ftp://ftp\.example\.org/lots/lots/lots/
-S:                    lots/lots/lots/lots/lots/lots/lots/
-S:                    rhubard\.txt"
-S: 
+S: \* 1 FETCH \(BODY\[4\.1\.MIME\] \{0\}
 S: \)
 S: A19 OK FETCH completed\.
 C: A20 FETCH 1 (BODY[4.2])
-S: \* 1 FETCH \(BODY\[4\.2\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\] \{0\}
+S: \)
 S: A20 OK FETCH completed\.
 C: A21 FETCH 1 (BODY[4.2.HEADER])
-S: \* 1 FETCH \(BODY\[4\.2\.HEADER\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\.HEADER\] \{0\}
+S: \)
 S: A21 OK FETCH completed\.
 C: A22 FETCH 1 (BODY[4.2.TEXT])
-S: \* 1 FETCH \(BODY\[4\.2\.TEXT\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\.TEXT\] \{0\}
+S: \)
 S: A22 OK FETCH completed\.
 C: A23 FETCH 1 (BODY[4.2.1])
-S: \* 1 FETCH \(BODY\[4\.2\.1\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\.1\] \{0\}
+S: \)
 S: A23 OK FETCH completed\.
 C: A24 FETCH 1 (BODY[4.2.2])
-S: \* 1 FETCH \(BODY\[4\.2\.2\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\.2\] \{0\}
+S: \)
 S: A24 OK FETCH completed\.
 C: A25 FETCH 1 (BODY[4.2.2.1])
-S: \* 1 FETCH \(BODY\[4\.2\.2\.1\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\.2\.1\] \{0\}
+S: \)
 S: A25 OK FETCH completed\.
 C: A26 FETCH 1 (BODY[4.2.2.2])
-S: \* 1 FETCH \(BODY\[4\.2\.2\.2\] NIL\)
+S: \* 1 FETCH \(BODY\[4\.2\.2\.2\] \{0\}
+S: \)
 S: A26 OK FETCH completed\.
 C: A27 FETCH 1:* (BODY BODYSTRUCTURE)
-S: \* 1 FETCH \(BODY \(\("text" "plain" \("charset" "us-ascii"\) NIL NIL "7bit" 781 17\)\("image" "png" \("name" "blob\.png"\) NIL NIL "base64" 492\)\("image" "png" \("name" "blob\.png"\) NIL NIL "base64" 492\)\("text" "plain" \("name" "rhubarb\.txt" "charset" "us-ascii"\) NIL NIL "quoted-printable" 3193 41\)\("text" "plain" \("charset" "us-ascii"\) NIL NIL "7bit" 0 0\) "mixed"\) BODYSTRUCTURE \(\("text" "plain" \("charset" "us-ascii"\) NIL NIL "7bit" 781 17 NIL NIL NIL\)\("image" "png" \("name" "blob\.png"\) NIL NIL "base64" 492 NIL \("attachment" \("filename" "blob\.png" "modification-date" "Sun, 21 Jun 2008 15:32:18 \+0000" "creation-date" "Sat, 20 Jun 2008 10:15:09 \+0000" "read-date" "Mon, 22 Jun 2008 12:08:56 \+0000" "size" "482"\)\) NIL\)\("image" "png" \("name" "blob\.png"\) NIL NIL "base64" 492 NIL \("attachment" \("filename" "blob\.png"\)\) NIL\)\("text" "plain" \("name" "rhubarb\.txt" "charset" "us-ascii"\) NIL NIL "quoted-printable" 3193 41 NIL \("attachment" \("
 filename" "rhubarb\.txt"\)\) \("en" "en-US" "en-CA" "en-AU"\)\)\("text" "plain" \("charset" "us-ascii"\) NIL NIL "7bit" 0 0 NIL NIL NIL\) "mixed" \("boundary" ""\) NIL NIL\)\)
-S: \* 2 FETCH \(BODY \(\("text" "plain" \("charset" "US-ASCII"\) NIL NIL "7bit" 15 1\)\("text" "plain" \("charset" "US-ASCII"\) NIL NIL "7bit" 18 1\)\("text" "plain" \("charset" "US-ASCII"\) NIL NIL "7bit" 16 1\) "alternative"\) BODYSTRUCTURE \(\("text" "plain" \("charset" "US-ASCII"\) NIL NIL "7bit" 15 1 NIL NIL \("en" "en-US" "en-CA"\)\)\("text" "plain" \("charset" "US-ASCII"\) NIL NIL "7bit" 18 1 NIL NIL \("fr" "fr-Latn-CA"\)\)\("text" "plain" \("charset" "US-ASCII"\) NIL NIL "7bit" 16 1 NIL NIL \("nl-BE"\)\) "alternative" \("boundary" "1729"\) NIL NIL\)\)
+S: \* 1 FETCH \(BODY \(\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 781 17\)\("IMAGE" "PNG" \("name" "blob\.png"\) NIL NIL "BASE64" 492\)\("IMAGE" "PNG" \("name" "blob\.png"\) NIL NIL "BASE64" 492\)\("TEXT" "PLAIN" \("name" "rhubarb\.txt" "charset" "us-ascii"\) NIL NIL "QUOTED-PRINTABLE" 3193 41\) "MIXED"\) BODYSTRUCTURE \(\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 781 17 NIL NIL NIL "relative/license.txt"\)\("IMAGE" "PNG" \("name" "blob\.png"\) NIL NIL "BASE64" 492 NIL \("attachment" \("creation-date" "Sat, 20 Jun 2008 10:15:09 \+0000" "filename" "blob\.png" "modification-date" "Sun, 21 Jun 2008 15:32:18 \+0000" "read-date" "Mon, 22 Jun 2008 12:08:56 \+0000" "size" "482"\)\) NIL "http://www.example.org/blob.png"\)\("IMAGE" "PNG" \("name" "blob\.png"\) NIL NIL "BASE64" 492 NIL \("attachment" \("filename" "blob\.png"\)\) NIL "http://www.example.org/blob.png"\)\("TEXT" "PLAIN" \("name" "rhubarb\.txt" "charset" "us-ascii"\) NIL NIL "QUOTED-PRINTABLE" 3
 193 41 NIL \("attachment" \("filename" "rhubarb\.txt"\)\) \("en" "en-US" "en-CA" "en-AU"\) "ftp://ftp.example.org/lots/lots/lots/lots/lots/lots/lots/lots/lots/lots/rhubard.txt"\) "MIXED" \("boundary" "=-tIdGYVstQJghyEDATnJ\+"\) NIL NIL "http://www.example.org/"\)\)
+S: \* 2 FETCH \(BODY \(\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 15 1\)\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 18 1\)\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 16 1\) "ALTERNATIVE"\) BODYSTRUCTURE \(\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 15 1 NIL NIL \("en" "en-US" "en-CA"\) NIL\)\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 18 1 NIL NIL \("fr" "fr-Latn-CA"\) NIL\)\("TEXT" "PLAIN" \("charset" "us-ascii"\) NIL NIL "7BIT" 16 1 NIL NIL \("nl-BE"\) NIL\) "ALTERNATIVE" \("boundary" "1729"\) NIL NIL NIL\)\)
 S: A27 OK FETCH completed\.
 C: A28 DELETE testmailbox
-S: A28 OK DELETE completed\.
\ No newline at end of file
+S: A28 OK DELETE completed\.

Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java Sat Jul 26 10:14:41 2008
@@ -332,4 +332,6 @@
      * @throws IOException
      */
     public ImapResponseComposer nillableComposition(String masterQuote, String[] quotes) throws IOException;
+
+    public void skipNextSpace() throws IOException;
 }
\ No newline at end of file

Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java Sat Jul 26 10:14:41 2008
@@ -72,19 +72,19 @@
     private void encodeBody(ImapResponseComposer composer, Structure body) throws IOException {
         if (body != null) {
             composer.message(ImapConstants.FETCH_BODY);
-            encodeStructure(composer, body, false);
+            encodeStructure(composer, body, false, false);
         }
     }
 
     private void encodeBodyStructure(ImapResponseComposer composer, Structure bodyStructure) throws IOException {
         if (bodyStructure != null) {
             composer.message(ImapConstants.FETCH_BODY_STRUCTURE);
-            encodeStructure(composer, bodyStructure, true);
+            encodeStructure(composer, bodyStructure, true, false);
         }
     }
     
     private void encodeStructure(final ImapResponseComposer composer, 
-            final Structure structure, final boolean includeExtensions) throws IOException {
+            final Structure structure, final boolean includeExtensions, final boolean isInnerPart) throws IOException {
         
         final String mediaType;
         final String subType;
@@ -96,11 +96,14 @@
             mediaType = rawMediaType;
             subType = structure.getSubType();
         }
-        encodeStructure(composer, structure, includeExtensions, mediaType, subType);
+        encodeStructure(composer, structure, includeExtensions, mediaType, subType, isInnerPart);
     }
 
     private void encodeStructure(final ImapResponseComposer composer, final Structure structure, 
-            final boolean includeExtensions, final String mediaType, final String subType) throws IOException {
+            final boolean includeExtensions, final String mediaType, final String subType, boolean isInnerPart) throws IOException {
+        if (isInnerPart) {
+            composer.skipNextSpace();
+        }
         if (ImapConstants.MIME_TYPE_MULTIPART.equalsIgnoreCase(mediaType)) {
             
             encodeMultipart(composer, structure, subType, includeExtensions);
@@ -195,15 +198,16 @@
         
         for (Iterator it = structure.parts(); it.hasNext();) {
             final Structure part = (Structure) it.next();
-            encodeStructure(composer, part, includeExtensions);
+            encodeStructure(composer, part, includeExtensions, true);
         }
         
+        composer.quoteUpperCaseAscii(subType);
         if (includeExtensions) {
             final String[] languages = languages(structure);
             composer.nillableQuotes(structure.getParameters());
             bodyFldDsp(structure, composer).nillableQuotes(languages).nillableQuote(structure.getLocation());
         }
-        composer.upperCaseAscii(subType).closeParen();
+        composer.closeParen();
     }
 
     private String[] languages(Structure structure) {
@@ -225,7 +229,7 @@
         
         encodeBodyFields(composer, structure, mediaType, subType);
         encodeEnvelope(composer, envelope);
-        encodeStructure(composer, embeddedStructure, includeExtensions);
+        encodeStructure(composer, embeddedStructure, includeExtensions, true);
         composer.message(lines);
         
         if (includeExtensions) {

Modified: james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalHostSystem.java
URL: http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalHostSystem.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalHostSystem.java (original)
+++ james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalHostSystem.java Sat Jul 26 10:14:41 2008
@@ -304,7 +304,7 @@
     }
     
     static class ByteBufferOutputStream extends OutputStream {
-        ByteBuffer buffer = ByteBuffer.allocate(8192);
+        ByteBuffer buffer = ByteBuffer.allocate(16384);
         Charset ascii = Charset.forName("ASCII");
         Continuation continuation;
         boolean matchPlus = false;

Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java
URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java (original)
+++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java Sat Jul 26 10:14:41 2008
@@ -38,16 +38,49 @@
     public static MimeDescriptorImpl build(final InputStream stream) throws IOException {
         final MimeTokenStream parser = MimeTokenStream.createMaximalDescriptorStream();
         parser.parse(stream);
+        return createDescriptor(parser);
+    }
+
+    private static MimeDescriptorImpl createDescriptor(
+            final MimeTokenStream parser) throws IOException, MimeException {
         int next = parser.next();
-        while (next != MimeTokenStream.T_BODY && next != MimeTokenStream.T_END_OF_STREAM) { 
+        while (next != MimeTokenStream.T_BODY && next != MimeTokenStream.T_END_OF_STREAM
+                && next != MimeTokenStream.T_START_MULTIPART) { 
             next = parser.next();
-        }
+        }        
         
-        if (next == MimeTokenStream.T_END_OF_STREAM) {
-            throw new MimeException("Premature end of stream");
+        final MimeDescriptorImpl mimeDescriptorImpl;
+        switch (next) {
+            case MimeTokenStream.T_BODY:
+                mimeDescriptorImpl = simplePartDescriptor(parser);
+                break;
+            case MimeTokenStream.T_START_MULTIPART:
+                mimeDescriptorImpl = compositePartDescriptor(parser);
+                break;
+            case MimeTokenStream.T_END_OF_STREAM:
+                throw new MimeException("Premature end of stream");
+            default:
+                throw new MimeException("Unexpected parse state");
         }
-        
+        return mimeDescriptorImpl;
+    }
+
+    private static MimeDescriptorImpl compositePartDescriptor(
+            final MimeTokenStream parser) throws IOException {
         MaximalBodyDescriptor descriptor = (MaximalBodyDescriptor) parser.getBodyDescriptor();
+        MimeDescriptorImpl mimeDescriptor = createDescriptor(0, 0, descriptor);
+        int next = parser.next();
+        while (next != MimeTokenStream.T_END_MULTIPART && next != MimeTokenStream.T_END_OF_STREAM) {
+            if (next == MimeTokenStream.T_START_BODYPART) {
+                mimeDescriptor.addPart(createDescriptor(parser));
+            }
+            next = parser.next();
+        }
+        return mimeDescriptor;
+    }
+    
+    private static MimeDescriptorImpl simplePartDescriptor(
+            final MimeTokenStream parser) throws IOException {
         final InputStream body = parser.getInputStream();
         long bodyOctets = 0;
         long lines = 0;
@@ -58,6 +91,14 @@
             bodyOctets++;
         }
         
+        MaximalBodyDescriptor descriptor = (MaximalBodyDescriptor) parser.getBodyDescriptor();
+        final MimeDescriptorImpl mimeDescriptorImpl = createDescriptor(
+                bodyOctets, lines, descriptor);
+        return mimeDescriptorImpl;
+    }
+
+    private static MimeDescriptorImpl createDescriptor(long bodyOctets,
+            long lines, MaximalBodyDescriptor descriptor) {
         final String contentDescription = descriptor.getContentDescription();
         final String contentId = descriptor.getContentId();
         
@@ -86,6 +127,10 @@
         if (header != null) {
             contentTypeParameters.add(header);
         }
+        final String boundary = descriptor.getBoundary();
+        if (boundary != null) {
+            contentTypeParameters.add(new Header("boundary", boundary));
+        }
         final List languages = descriptor.getContentLanguage();
         final String disposition = descriptor.getContentDispositionType();
         final Map dispositionParams = descriptor.getContentDispositionParameters();
@@ -93,9 +138,10 @@
         final Collection parts = new ArrayList();
         final String location = descriptor.getContentLocation();
         final String md5 = descriptor.getContentMD5Raw();
-        return new MimeDescriptorImpl(bodyOctets, contentDescription, contentId, lines, subType, type, transferEncoding,
+        final MimeDescriptorImpl mimeDescriptorImpl = new MimeDescriptorImpl(bodyOctets, contentDescription, contentId, lines, subType, type, transferEncoding,
                 headers, contentTypeParameters, languages, disposition, dispositionParams, embeddedMessage, parts,
                 location, md5);
+        return mimeDescriptorImpl;
     }
     
     private final long bodyOctets;
@@ -183,6 +229,10 @@
         return parts.iterator();
     }
 
+    private void addPart(MimeDescriptor descriptor) {
+        parts.add(descriptor);
+    }
+    
     public List getLanguages() {
         return languages;
     }

Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java
URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java (original)
+++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java Sat Jul 26 10:14:41 2008
@@ -35,6 +35,7 @@
     
     private MimeTokenStream parser;
     private boolean empty = false;
+    private boolean topLevel = true;
     
     public PartContentBuilder() {
         parser = new MimeTokenStream();
@@ -47,10 +48,27 @@
     public void parse(final InputStream in) {
         parser.setRecursionMode(MimeTokenStream.M_RECURSE);
         parser.parse(in);
+        topLevel = true;
     }
     
-    public void to(int position) throws IOException, MimeException {
+    private void skipToStartOfInner(int position) throws IOException {
+        final int state = parser.next();
+        switch (state) {
+            case MimeTokenStream.T_START_MULTIPART: break;
+            case MimeTokenStream.T_START_MESSAGE: break;
+            case MimeTokenStream.T_END_OF_STREAM: throw new PartNotFoundException(position);
+            case MimeTokenStream.T_END_BODYPART: throw new PartNotFoundException(position);
+            default: skipToStartOfInner(position);
+        }
+    }
+    
+    public void to(int position) throws IOException {
         try {
+            if (topLevel) {
+                topLevel = false;
+            } else {
+                skipToStartOfInner(position);
+            }
             for (int count=0;count<position;) {
                 final int state = parser.next();
                 switch (state) {
@@ -77,11 +95,11 @@
         }
     }
     
-    private void ignoreInnerMessage() throws IOException, MimeException {
+    private void ignoreInnerMessage() throws IOException {
         for (int state = parser.next(); state != MimeTokenStream.T_END_MULTIPART; state = parser.next()) {
             switch (state) {
                 case MimeTokenStream.T_END_OF_STREAM:
-                    throw new IOException("Unexpected EOF");
+                    throw new UnexpectedEOFException();
                     
                 case MimeTokenStream.T_START_MULTIPART:
                     ignoreInnerMessage();
@@ -90,61 +108,84 @@
         }
     }
     
-    public Content getFullContent() throws IOException, MimeException {
+    public Content getFullContent() throws IOException {
         final List headers = getMimeHeaders();
         final byte[] content = mimeBodyContent();
         return new FullContent(content, headers);
     }
     
-    public Content getMessageBodyContent() throws IOException, MimeException {
+    public Content getMessageBodyContent() throws IOException {
         final byte[] content = messageBodyContent();
         return new ByteContent(content);
     }
 
-    private byte[] messageBodyContent() throws IOException, MimeException {
+    private byte[] messageBodyContent() throws IOException {
         final byte[] content;
         if (empty) {
             content = EMPTY;
         } else {
-            advancedToMessage();
-            parser.setRecursionMode(MimeTokenStream.M_FLAT);
-            for ( int state = parser.getState(); 
-                    state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; 
-                    state = parser.next()) {
-                if (state == MimeTokenStream.T_END_OF_STREAM) {
-                    throw new IOException("Unexpected EOF");
+            boolean valid;
+            try 
+            {
+                advancedToMessage();
+                valid = true;
+            } catch (UnexpectedEOFException e) {
+                // No TEXT part
+                valid = false;
+            }
+            if (valid) {
+                parser.setRecursionMode(MimeTokenStream.M_FLAT);
+                for ( int state = parser.getState(); 
+                        state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; 
+                        state = parser.next()) {
+                    if (state == MimeTokenStream.T_END_OF_STREAM) {
+                        valid = false;
+                        break;
+                    }
                 }
+                if (valid) {
+                    content = MessageUtils.toByteArray(parser.getInputStream());
+                } else {
+                    content = EMPTY;
+                }
+            } else {
+                content = EMPTY;
             }
-            content = MessageUtils.toByteArray(parser.getInputStream());
         }
         return content;
     }
     
-    public Content getMimeBodyContent() throws IOException, MimeException {
+    public Content getMimeBodyContent() throws IOException {
         final byte[] content = mimeBodyContent();
         return new ByteContent(content);
     }
 
-    private byte[] mimeBodyContent() throws IOException, MimeException {
+    private byte[] mimeBodyContent() throws IOException {
         final byte[] content;
         if (empty) {
             content = EMPTY;
         } else {
             parser.setRecursionMode(MimeTokenStream.M_FLAT);
+            boolean valid = true;
             for ( int state = parser.getState(); 
                     state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; 
                     state = parser.next()) {
                 if (state == MimeTokenStream.T_END_OF_STREAM) {
-                    throw new IOException("Unexpected EOF");
+                    valid = false;
+                    break;
                 }
             }
-            content = MessageUtils.toByteArray(parser.getInputStream());
+            if (valid) {
+                content = MessageUtils.toByteArray(parser.getInputStream());
+            } else {
+                content = EMPTY;
+            }
         }
         String temp = new String(content);
         return content;
     }
     
-    public List getMimeHeaders() throws IOException, MimeException {
+    public List getMimeHeaders() throws IOException {
         final List results;
         if (empty) {
             results = Collections.EMPTY_LIST;
@@ -153,7 +194,7 @@
             for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) {
                 switch (state) {
                     case MimeTokenStream.T_END_OF_STREAM:
-                        throw new IOException("Unexpected EOF");
+                        throw new UnexpectedEOFException();
                         
                     case MimeTokenStream.T_FIELD:
                         final String fieldValue = parser.getFieldValue().trim();
@@ -167,39 +208,53 @@
         return results;
     }
     
-    public List getMessageHeaders() throws IOException, MimeException {
+    public List getMessageHeaders() throws IOException {
         final List results;
         if (empty) {
             results = Collections.EMPTY_LIST;
         } else {
-            advancedToMessage();
-                
             results = new ArrayList();
-            for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) {
-                switch (state) {
-                    case MimeTokenStream.T_END_OF_STREAM:
-                        throw new IOException("Unexpected EOF");
-                        
-                    case MimeTokenStream.T_FIELD:
-                        final String fieldValue = parser.getFieldValue().trim();
-                        final String fieldName = parser.getFieldName();
-                        Header header = new Header(fieldName, fieldValue);
-                        results.add(header);
-                        break;
+            try
+            {
+                advancedToMessage();
+                
+                for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) {
+                    switch (state) {
+                        case MimeTokenStream.T_END_OF_STREAM:
+                            throw new IOException("Unexpected EOF");
+                            
+                        case MimeTokenStream.T_FIELD:
+                            final String fieldValue = parser.getFieldValue().trim();
+                            final String fieldName = parser.getFieldName();
+                            Header header = new Header(fieldName, fieldValue);
+                            results.add(header);
+                            break;
+                    }
                 }
+            } catch (UnexpectedEOFException e) {
+                // No headers found
             }
         }
         return results;
     }
 
-    private void advancedToMessage() throws IOException, MimeException {
+    private void advancedToMessage() throws IOException {
         for (int state = parser.getState(); state != MimeTokenStream.T_START_MESSAGE; state = parser.next()) {
             if (state == MimeTokenStream.T_END_OF_STREAM) {
-                throw new IOException("Unexpected EOF");
+                throw new UnexpectedEOFException();
             }
         }
     }
     
+    public static final class UnexpectedEOFException extends MimeException {
+
+        private static final long serialVersionUID = -3755637466593055796L;
+
+        public UnexpectedEOFException() {
+            super("Unexpected EOF");
+        }        
+    }
+    
     public static final class PartNotFoundException extends MimeException {
 
         private static final long serialVersionUID = 7519976990944851574L;
@@ -214,7 +269,7 @@
             super("Part " + position + " not found.", e);
             this.position = position;
         }
-
+        
         public final int getPosition() {
             return position;
         }

Modified: james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java?rev=680015&r1=680014&r2=680015&view=diff
==============================================================================
--- james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java (original)
+++ james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java Sat Jul 26 10:14:41 2008
@@ -24,6 +24,8 @@
 import java.nio.charset.Charset;
 import java.util.List;
 
+import org.apache.james.mailboxmanager.torque.PartContentBuilder.PartNotFoundException;
+
 import junit.framework.TestCase;
 
 public class PartContentBuilderComplexMultipartTest extends TestCase {
@@ -96,7 +98,23 @@
     protected void tearDown() throws Exception {
         super.tearDown();
     }
-
+    
+    public void testShouldNotFoundSubPartOfNonMultiPartTopLevel() throws Exception {
+        int[] path = {1, 1};
+        for (int i=1;i<10;i++) {
+            path[1] = i;
+            checkNotPartFound(path);
+        }
+    }
+    
+    public void testShouldNotFoundSubPartOfNonMultiInnerPart() throws Exception {
+        int[] path = {2, 2, 1};
+        for (int i=1;i<10;i++) {
+            path[2] = i;
+            checkNotPartFound(path);
+        }
+    }
+    
     public void testShouldLocateOuterHtml() throws Exception {
         int[] path = {1};
         check(FULL_OUTER_HTML, OUTER_HTML_BODY, CONTENT_TYPE_HTML, path);
@@ -127,6 +145,15 @@
         check(FULL_INNER_TXT, INNER_PLAIN_BODY, CONTENT_TYPE_PLAIN, path);
     }
   
+    private void checkNotPartFound(int[] position) throws Exception {
+        try {
+            to(position);
+            fail("Part does not exist. Expected exception to be thrown.");
+        } catch (PartNotFoundException e) {
+            // expected
+        }
+    }
+    
     private void check(String full, String body, String contentType, int[] position) throws Exception {
         checkContentType(contentType, position);
         assertEquals(body, bodyContent(position));
@@ -163,7 +190,7 @@
     private void to(int[] path) throws Exception {
         InputStream in = new ByteArrayInputStream(Charset.forName("us-ascii").encode(MULTIPART_MIXED).array());
         builder.parse(in);
-        for (int i = 0; i < path.length; i++) {
+        for (int i=0;i<path.length;i++) {
             builder.to(path[i]);
         }
     }



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