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/03/08 17:05:56 UTC
svn commit: r634996 - in /james/mime4j/trunk/src:
main/java/org/apache/james/mime4j/ test/java/org/apache/james/mime4j/
Author: rdonkin
Date: Sat Mar 8 08:05:56 2008
New Revision: 634996
URL: http://svn.apache.org/viewvc?rev=634996&view=rev
Log:
Added getReader a conveniance method that returns a correct configured reader suitable for decoding bodies.
Added:
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
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=634996&r1=634995&r2=634996&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 Sat Mar 8 08:05:56 2008
@@ -21,12 +21,17 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
import org.apache.james.mime4j.util.MimeUtil;
@@ -777,6 +782,47 @@
return currentStateMachine.read();
}
+ /**
+ * Gets a reader configured for the current body or body part.
+ * The reader will return a transfer and charset decoded
+ * stream of characters based on the MIME fields with the standard
+ * defaults.
+ * This is a conveniance method and relies on {@link #getInputStream()}.
+ * Consult the javadoc for that method for known limitations.
+ *
+ * @return <code>Reader</code>, not null
+ * @see #getInputStream
+ * @throws IllegalStateException {@link #getState()} returns an
+ * invalid value
+ * @throws UnsupportedCharsetException if there is no JVM support
+ * for decoding the charset
+ * @throws IllegalCharsetNameException if the charset name specified
+ * in the mime type is illegal
+ */
+ public Reader getReader() {
+ final BodyDescriptor bodyDescriptor = getBodyDescriptor();
+ final String mimeCharset = bodyDescriptor.getCharset();
+ final String transferEncoding = bodyDescriptor.getTransferEncoding();
+ final Charset charset;
+ if (mimeCharset == null || "".equals(mimeCharset)) {
+ charset = Charset.forName("US-ASCII");
+ } else {
+ charset = Charset.forName(mimeCharset);
+ }
+
+ final InputStream inputStream;
+ final InputStream transferEncodedStream = getInputStream();
+ if (MimeUtil.isBase64Encoding(transferEncoding)) {
+ inputStream = new Base64InputStream(transferEncodedStream);
+ } else if (MimeUtil.isQuotedPrintableEncoded(transferEncoding)) {
+ inputStream = new QuotedPrintableInputStream(transferEncodedStream);
+ } else {
+ inputStream = transferEncodedStream;
+ }
+ final InputStreamReader result = new InputStreamReader(inputStream, charset);
+ return result;
+ }
+
/**
* This method is valid, if {@link #getState()} returns
* {@link #T_BODY}, or {@link #T_START_MULTIPART}. It returns the current
Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java?rev=634996&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java (added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java Sat Mar 8 08:05:56 2008
@@ -0,0 +1,111 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mime4j;
+
+
+public class EncodeUtils {
+
+ public static final int MASK = 0x3F;
+ public static final int FIRST_MASK = MASK << 18;
+ public static final int SECOND_MASK = MASK << 12;
+ public static final int THIRD_MASK = MASK << 6;
+ public static final int FORTH_MASK = MASK;
+
+ public static final byte[] ENCODING = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P' ,'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'};
+
+ public static final void main(String[] args) throws Exception {
+ byte[] bytes = {(byte) 0, (byte) 128, (byte) 0};
+ System.out.println(new String(toBase64(bytes)));
+ System.out.println(new String(toBase64("Hello, World".getBytes())));
+ System.out.println(new String(toBase64("Monday".getBytes())));
+ System.out.println(new String(toBase64("M\u00F6nchengladbach\r\n".getBytes("ISO-8859-1"))));
+ }
+
+ public static byte[] toBase64(byte[] in) {
+ int inputLength = in.length;
+ int outputLength = (int) Math.floor((4*inputLength) / 3f) + 3;
+ outputLength = outputLength + 2 * (int) Math.floor(outputLength / 76f);
+ byte[] results = new byte[outputLength];
+ int inputIndex = 0;
+ int outputIndex = 0;
+ while (inputLength - inputIndex > 2) {
+ int one = (toInt(in[inputIndex++]) << 16);
+ int two = (toInt(in[inputIndex++]) << 8);
+ int three = toInt(in[inputIndex++]);
+ int quantum = one | two | three;
+ int index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & THIRD_MASK) >> 6;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & FORTH_MASK);
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ }
+
+ switch (inputLength - inputIndex) {
+ case 1:
+ int quantum = in[inputIndex++] << 16;
+ int index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ outputIndex = setResult(results, outputIndex, (byte) '=');
+ outputIndex = setResult(results, outputIndex, (byte) '=');
+ break;
+
+ case 2:
+ quantum = (in[inputIndex++] << 16) + (in[inputIndex++] << 8);
+ index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & THIRD_MASK) >> 6;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ outputIndex = setResult(results, outputIndex, (byte) '=');
+ break;
+ }
+
+ return results;
+ }
+
+ private static int toInt(byte b) {
+ return (int)(b & 255);
+ }
+
+
+ private static int setResult(byte[] results, int outputIndex, byte value) {
+ results[outputIndex++] = value;
+ outputIndex = checkLineLength(results, outputIndex);
+ return outputIndex;
+ }
+
+
+ private static int checkLineLength(byte[] results, int outputIndex) {
+ if (outputIndex == 76 || outputIndex > 76 && (outputIndex - 2*Math.floor(outputIndex/76f - 1)) % 76 == 0) {
+ results[outputIndex++] = '\r';
+ results[outputIndex++] = '\n';
+ }
+ return outputIndex;
+ }
+}
Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java?rev=634996&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java (added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java Sat Mar 8 08:05:56 2008
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.james.mime4j;
+
+import java.nio.charset.Charset;
+
+public class ExampleMail {
+
+ public static final Charset US_ASCII = Charset.forName("US-ASCII");
+ public static final Charset LATIN1 = Charset.forName("ISO-8859-1");
+
+ public static final String ONE_PART_MIME_ASCII_BODY = "A single part MIME mail.\r\n";
+
+ public static final String RFC822_SIMPLE_BODY = "This is a very simple email.\r\n";
+
+ public static final String ONE_PART_MIME_8859_BODY = "M\u00F6nchengladbach\r\n";
+
+ public static final String ONE_PART_MIME_BASE64_LATIN1_BODY = "Hello Mo\u00F6nchengladbach\r\n";
+
+ public static final String ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY = "Sonnet LXXXI By William Shakespeare\r\n" +
+ "Or I shall live your epitaph to make,\r\n" +
+ "Or you survive when I in earth am rotten;\r\n" +
+ "From hence your memory death cannot take,\r\n" +
+ "Although in me each part will be forgotten.\r\n" +
+ "Your name from hence immortal life shall have,\r\n" +
+ "Though I, once gone, to all the world must die:\r\n" +
+ "The earth can yield me but a common grave,\r\n" +
+ "When you entombed in men's eyes shall lie.\r\n" +
+ "Your monument shall be my gentle verse,\r\n" +
+ "Which eyes not yet created shall o'er-read;\r\n" +
+ "And tongues to be, your being shall rehearse,\r\n" +
+ "When all the breathers of this world are dead;\r\n" +
+ " You still shall live,--such virtue hath my pen,--\r\n" +
+ " Where breath most breathes, even in the mouths of men.\r\n";
+
+ private static final byte[] ONE_PART_MIME_BASE64_LATIN1_ENCODED = EncodeUtils.toBase64(latin1(ONE_PART_MIME_BASE64_LATIN1_BODY));
+
+ public static final String ONE_PART_MIME_BASE64_ASCII_BODY = "Hello, World!\r\n";
+
+ private static final byte[] ONE_PART_MIME_BASE64_ASCII_ENCODED = EncodeUtils.toBase64(ascii(ONE_PART_MIME_BASE64_ASCII_BODY));
+
+ public static final String ONE_PART_MIME_ASCII = "Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <f4...@mail.gmail.com>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+ "To: \"James Developers List\" <se...@james.apache.org>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: 7bit\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: robertburrelldonkin@gmail.com\r\n" +
+ "\r\n" +
+ ONE_PART_MIME_ASCII_BODY;
+
+ public static final String ONE_PART_MIME_8859 = "Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <f4...@mail.gmail.com>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+ "To: \"James Developers List\" <se...@james.apache.org>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
+ "Content-Transfer-Encoding: 8bit\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: robertburrelldonkin@gmail.com\r\n" +
+ "\r\n" +
+ ONE_PART_MIME_8859_BODY;
+
+ public static final String ONE_PART_MIME_BASE64_ASCII_HEADERS = "Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <f4...@mail.gmail.com>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+ "To: \"James Developers List\" <se...@james.apache.org>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: robertburrelldonkin@gmail.com\r\n" +
+ "\r\n";
+
+ public static final String ONE_PART_MIME_BASE64_LATIN1_HEADERS = "Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <f4...@mail.gmail.com>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+ "To: \"James Developers List\" <se...@james.apache.org>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: robertburrelldonkin@gmail.com\r\n" +
+ "\r\n";
+
+ public static final String ONE_PART_MIME_QUOTED_PRINTABLE_ASCII = "Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <f4...@mail.gmail.com>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+ "To: \"James Developers List\" <se...@james.apache.org>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: Quoted-Printable\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: robertburrelldonkin@gmail.com\r\n" +
+ "\r\n" + breakLines(ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY.replaceAll("\r\n", "=0D=0A"));
+
+ public static final String RFC_SIMPLE =
+ "From: Timothy Tayler <ti...@example.org>\r\n" +
+ "To: Samual Smith <sa...@example.org>\r\n" +
+ "Date: Thu, 14 Feb 2008 12:00:00 +0000 (GMT)\r\n" +
+ "Subject: A Simple Email\r\n" +
+ "\r\n" +
+ RFC822_SIMPLE_BODY;
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_7BIT = "Sonnet XXXIII By William Shakespeare\r\n" +
+ "\r\n" +
+ "Full many a glorious morning have I seen\r\n" +
+ "Flatter the mountain tops with sovereign eye,\r\n" +
+ "Kissing with golden face the meadows green,\r\n" +
+ "Gilding pale streams with heavenly alchemy;\r\n" +
+ "Anon permit the basest clouds to ride\r\n" +
+ "With ugly rack on his celestial face,\r\n" +
+ "And from the forlorn world his visage hide,\r\n" +
+ "Stealing unseen to west with this disgrace:\r\n" +
+ "Even so my sun one early morn did shine,\r\n" +
+ "With all triumphant splendour on my brow;\r\n" +
+ "But out! alack! he was but one hour mine,\r\n" +
+ "The region cloud hath mask'd him from me now.\r\n" +
+ " Yet him for this my love no whit disdaineth;\r\n" +
+ " Suns of the world may stain when heaven's sun staineth.\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_QUOTED_PRINTABLE = "Sonnet XXXV By William Shakespeare\r\n" +
+ "\r\n" +
+ "No more be griev'd at that which thou hast done:\r\n" +
+ "Roses have thorns, and silver fountains mud:\r\n" +
+ "Clouds and eclipses stain both moon and sun,\r\n" +
+ "And loathsome canker lives in sweetest bud.\r\n" +
+ "All men make faults, and even I in this,\r\n" +
+ "Authorizing thy trespass with compare,\r\n" +
+ "Myself corrupting, salving thy amiss,\r\n" +
+ "Excusing thy sins more than thy sins are;\r\n" +
+ "For to thy sensual fault I bring in sense,--\r\n" +
+ "Thy adverse party is thy advocate,--\r\n" +
+ "And 'gainst myself a lawful plea commence:\r\n" +
+ "Such civil war is in my love and hate,\r\n" +
+ " That I an accessary needs must be,\r\n" +
+ " To that sweet thief which sourly robs from me.\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BASE64 = "Sonnet XXXVIII By William Shakespeare\r\n" +
+ "\r\n" +
+ "How can my muse want subject to invent,\r\n" +
+ "While thou dost breathe, that pour'st into my verse\r\n" +
+ "Thine own sweet argument, too excellent\r\n" +
+ "For every vulgar paper to rehearse?\r\n" +
+ "O! give thy self the thanks, if aught in me\r\n" +
+ "Worthy perusal stand against thy sight;\r\n" +
+ "For who's so dumb that cannot write to thee,\r\n" +
+ "When thou thy self dost give invention light?\r\n" +
+ "Be thou the tenth Muse, ten times more in worth\r\n" +
+ "Than those old nine which rhymers invocate;\r\n" +
+ "And he that calls on thee, let him bring forth\r\n" +
+ "Eternal numbers to outlive long date.\r\n" +
+ " If my slight muse do please these curious days,\r\n" +
+ " The pain be mine, but thine shall be the praise.\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_ONE =
+ "From: Timothy Tayler <ti...@example.org>\r\n" +
+ "To: Samual Smith <sa...@example.org>\r\n" +
+ "Date: Thu, 14 Feb 2008 12:00:00 +0000 (GMT)\r\n" +
+ "Subject: A Multipart Email\r\n" +
+ "Content-Type: multipart/mixed;boundary=1729\r\n" +
+ "\r\n" +
+ "Start with a preamble\r\n" +
+ "\r\n" +
+ "--1729\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: 7bit\r\n\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_TWO =
+ "\r\n--1729\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: Quoted-Printable\r\n\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_THREE =
+ "\r\n--1729\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: base64\r\n\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_END =
+ "\r\n--1729--\r\n";
+
+ private static final byte[][] MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTE_ARRAYS = {
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_ONE),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_7BIT),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_TWO),
+ ascii(breakLines(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_QUOTED_PRINTABLE.replaceAll("\r\n", "=0D=0A"))),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_THREE),
+ EncodeUtils.toBase64(ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BASE64)),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_END),
+ };
+ public static final byte[] MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTES = join(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTE_ARRAYS);
+ public static final byte[] ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BYTES = ascii(ONE_PART_MIME_QUOTED_PRINTABLE_ASCII);
+ public static final byte[] ONE_PART_MIME_BASE64_LATIN1_BYTES = join(ascii(ONE_PART_MIME_BASE64_LATIN1_HEADERS), ONE_PART_MIME_BASE64_LATIN1_ENCODED);
+ public static final byte[] ONE_PART_MIME_BASE64_ASCII_BYTES = join(ascii(ONE_PART_MIME_BASE64_ASCII_HEADERS), ONE_PART_MIME_BASE64_ASCII_ENCODED);
+ public static final byte[] RFC822_SIMPLE_BYTES = US_ASCII.encode(RFC_SIMPLE).array();
+ public static final byte[] ONE_PART_MIME_ASCII_BYTES = US_ASCII.encode(ONE_PART_MIME_ASCII).array();
+ public static final byte[] ONE_PART_MIME_8859_BYTES = LATIN1.encode(ONE_PART_MIME_8859).array();
+
+ public static final byte[] ascii(String text) {
+
+ return US_ASCII.encode(text).array();
+ }
+
+ public static final byte[] latin1(String text) {
+
+ return LATIN1.encode(text).array();
+ }
+
+ public static final byte[] join(byte[] one, byte[] two) {
+ byte[] results = new byte[one.length + two.length];
+ System.arraycopy(one, 0, results, 0, one.length);
+ System.arraycopy(two, 0, results, one.length, two.length);
+ return results;
+ }
+
+ public static final byte[] join(byte[][] byteArrays) {
+ int length = 0;
+ for (int i = 0; i < byteArrays.length; i++) {
+ byte[] bytes = byteArrays[i];
+ length += bytes.length;
+ }
+ byte[] results = new byte[length];
+ int count = 0;
+ for (int i = 0; i < byteArrays.length; i++) {
+ byte[] bytes = byteArrays[i];
+ System.arraycopy(bytes, 0, results, count, bytes.length);
+ count += bytes.length;
+ }
+ return results;
+ }
+
+ public static String breakLines(String original) {
+ StringBuffer buffer = new StringBuffer(original);
+ int count = 76;
+ while(count < buffer.length()) {
+ if (buffer.charAt(count) == '=') {
+ count = count - 1;
+ } else if (buffer.charAt(count-1) == '=') {
+ count = count - 4;
+ } else if (buffer.charAt(count-2) == '=') {
+ count = count - 3;
+ }
+ buffer.insert(count, '\n');
+ buffer.insert(count, '\r');
+ buffer.insert(count, '=');
+ count += 79;
+ }
+ final String result = buffer.toString();
+ return result;
+ }
+}
Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java?rev=634996&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java (added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java Sat Mar 8 08:05:56 2008
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.james.mime4j;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.apache.commons.io.IOUtils;
+
+import junit.framework.TestCase;
+
+public class MimeTokenStreamReaderTest extends TestCase {
+
+ MimeTokenStream parser;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parser = new MimeTokenStream();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testShouldReadSimpleBody() throws Exception {
+ byte[] bytes = ExampleMail.RFC822_SIMPLE_BYTES;
+ String body = ExampleMail.RFC822_SIMPLE_BODY;
+ checkSimpleMail(bytes, body, 4);
+ }
+
+ public void testShouldReadOnePartMimeASCIIBody() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_ASCII_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_ASCII_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMime8859Body() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_8859_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_8859_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMimeBase64ASCIIBody() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_BASE64_ASCII_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_BASE64_ASCII_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMimeBase64Latin1Body() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_BASE64_LATIN1_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_BASE64_LATIN1_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMimeQuotedPrintable() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadPartBodies() throws IOException, MimeException {
+ InputStream in = new ByteArrayInputStream(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTES);
+ parser.parse(in);
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ for (int i=0;i<5;i++) {
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ }
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_MULTIPART),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_PREAMBLE),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_BODYPART),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_7BIT);
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_BODYPART),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_BODYPART),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_QUOTED_PRINTABLE);
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_BODYPART),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_BODYPART),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BASE64);
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
+
+ }
+
+ private void checkSimpleMail(byte[] bytes, String body, int fields) throws IOException, MimeException {
+ InputStream in = new ByteArrayInputStream(bytes);
+ parser.parse(in);
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ for (int i=0;i<fields;i++) {
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ }
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+ assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(body);
+ }
+
+ private void checkBody(String body) throws IOException {
+ Reader reader = parser.getReader();
+ assertNotNull(reader);
+ assertEquals(body, IOUtils.toString(reader));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org