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/11/30 21:59:37 UTC

svn commit: r721894 - in /james/mime4j/trunk: ./ src/main/java/org/apache/james/mime4j/descriptor/ src/main/java/org/apache/james/mime4j/message/ src/test/java/org/apache/james/mime4j/message/

Author: rdonkin
Date: Sun Nov 30 12:59:36 2008
New Revision: 721894

URL: http://svn.apache.org/viewvc?rev=721894&view=rev
Log:
https://issues.apache.org/jira/browse/MIME4J-87 Add a factory for creating message bodies. Contributed by Markus Wiederkehr MIME4J-87.

Added:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyFactory.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageBinaryBody.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageTextBody.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StringTextBody.java
Removed:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java
Modified:
    james/mime4j/trunk/RELEASE_NOTES.txt
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/descriptor/ContentDescriptor.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java
    james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java

Modified: james/mime4j/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/RELEASE_NOTES.txt?rev=721894&r1=721893&r2=721894&view=diff
==============================================================================
--- james/mime4j/trunk/RELEASE_NOTES.txt (original)
+++ james/mime4j/trunk/RELEASE_NOTES.txt Sun Nov 30 12:59:36 2008
@@ -1,3 +1,13 @@
+Since Release 0.5
+-------------------
+
+Notes
+-----
+ * BodyFactory introduces allowing more flexible storate for Message parts. TempFileTextBody
+   and TempFileBinaryBody removed.
+   [https://issues.apache.org/jira/browse/MIME4J-87]
+ * Temporary text body storage for Message parts now defaults to US-ASCII (was ISO-8859-1)
+
 Release 0.5
 -------------------
 

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/descriptor/ContentDescriptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/descriptor/ContentDescriptor.java?rev=721894&r1=721893&r2=721894&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/descriptor/ContentDescriptor.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/descriptor/ContentDescriptor.java Sun Nov 30 12:59:36 2008
@@ -64,7 +64,7 @@
      * @return Character set, which has been parsed from the
      *   content-type definition. Not null for <code>TEXT</code> types, when unset will
      *   be set to default <code>us-ascii</code>. For other types, when unset,
-     *   null will be returnedsvn s
+     *   null will be returned.
      */
     String getCharset();
 

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyFactory.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyFactory.java?rev=721894&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyFactory.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyFactory.java Sun Nov 30 12:59:36 2008
@@ -0,0 +1,130 @@
+/****************************************************************
+ * 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.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.message.storage.DefaultStorageProvider;
+import org.apache.james.mime4j.message.storage.Storage;
+import org.apache.james.mime4j.message.storage.StorageProvider;
+import org.apache.james.mime4j.util.CharsetUtil;
+import org.apache.james.mime4j.util.MessageUtils;
+
+/**
+ * Factory for creating message bodies.
+ */
+public class BodyFactory {
+
+    private static Log log = LogFactory.getLog(BodyFactory.class);
+
+    private static final Charset FALLBACK_CHARSET = MessageUtils.DEFAULT_CHARSET;
+
+    private StorageProvider storageProvider;
+
+    public BodyFactory() {
+        this.storageProvider = DefaultStorageProvider.getInstance();
+    }
+
+    public BodyFactory(StorageProvider storageProvider) {
+        if (storageProvider == null)
+            storageProvider = DefaultStorageProvider.getInstance();
+
+        this.storageProvider = storageProvider;
+    }
+
+    public BinaryBody binaryBody(InputStream is) throws IOException {
+        if (is == null)
+            throw new IllegalArgumentException();
+
+        Storage storage = storageProvider.store(is);
+        return new StorageBinaryBody(storage);
+    }
+
+    public TextBody textBody(InputStream is) throws IOException {
+        if (is == null)
+            throw new IllegalArgumentException();
+
+        Storage storage = storageProvider.store(is);
+        return new StorageTextBody(storage, MessageUtils.DEFAULT_CHARSET);
+    }
+
+    public TextBody textBody(InputStream is, String mimeCharset)
+            throws IOException {
+        if (is == null)
+            throw new IllegalArgumentException();
+        if (mimeCharset == null)
+            throw new IllegalArgumentException();
+
+        Storage storage = storageProvider.store(is);
+        Charset charset = toJavaCharset(mimeCharset, false);
+        return new StorageTextBody(storage, charset);
+    }
+
+    public TextBody textBody(String text) {
+        if (text == null)
+            throw new IllegalArgumentException();
+
+        return new StringTextBody(text, MessageUtils.DEFAULT_CHARSET);
+    }
+
+    public TextBody textBody(String text, String mimeCharset) {
+        if (text == null)
+            throw new IllegalArgumentException();
+        if (mimeCharset == null)
+            throw new IllegalArgumentException();
+
+        Charset charset = toJavaCharset(mimeCharset, true);
+        return new StringTextBody(text, charset);
+    }
+
+    private static Charset toJavaCharset(String mimeCharset, boolean forEncoding) {
+        String charset = CharsetUtil.toJavaCharset(mimeCharset);
+        if (charset == null) {
+            if (log.isWarnEnabled())
+                log.warn("MIME charset '" + mimeCharset + "' has no "
+                        + "corresponding Java charset. Using "
+                        + FALLBACK_CHARSET + " instead.");
+            return FALLBACK_CHARSET;
+        }
+
+        if (forEncoding && !CharsetUtil.isEncodingSupported(charset)) {
+            if (log.isWarnEnabled())
+                log.warn("MIME charset '" + mimeCharset
+                        + "' does not support encoding. Using "
+                        + FALLBACK_CHARSET + " instead.");
+            return FALLBACK_CHARSET;
+        }
+
+        if (!forEncoding && !CharsetUtil.isDecodingSupported(charset)) {
+            if (log.isWarnEnabled())
+                log.warn("MIME charset '" + mimeCharset
+                        + "' does not support decoding. Using "
+                        + FALLBACK_CHARSET + " instead.");
+            return FALLBACK_CHARSET;
+        }
+
+        return Charset.forName(charset);
+    }
+
+}

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java?rev=721894&r1=721893&r2=721894&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java Sun Nov 30 12:59:36 2008
@@ -28,7 +28,6 @@
 import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
 import org.apache.james.mime4j.descriptor.BodyDescriptor;
 import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.message.storage.DefaultStorageProvider;
 import org.apache.james.mime4j.message.storage.StorageProvider;
 import org.apache.james.mime4j.parser.ContentHandler;
 import org.apache.james.mime4j.util.CharArrayBuffer;
@@ -37,20 +36,17 @@
 public class MessageBuilder implements ContentHandler {
 
     private final Entity entity;
-    private final StorageProvider storageProvider;
+    private final BodyFactory bodyFactory;
     private Stack<Object> stack = new Stack<Object>();
     
     public MessageBuilder(Entity entity) {
         this.entity = entity;
-        this.storageProvider = DefaultStorageProvider.getInstance();
+        this.bodyFactory = new BodyFactory();
     }
     
     public MessageBuilder(Entity entity, StorageProvider storageProvider) {
-        if (storageProvider == null)
-            storageProvider = DefaultStorageProvider.getInstance();
-
         this.entity = entity;
-        this.storageProvider = storageProvider;
+        this.bodyFactory = new BodyFactory(storageProvider);
     }
     
     private void expect(Class<?> c) {
@@ -141,10 +137,9 @@
         }
         
         if (bd.getMimeType().startsWith("text/")) {
-            body = new TempFileTextBody(storageProvider, decodedStream, bd
-                    .getCharset());
+            body = bodyFactory.textBody(decodedStream, bd.getCharset());
         } else {
-            body = new TempFileBinaryBody(storageProvider, decodedStream);
+            body = bodyFactory.binaryBody(decodedStream);
         }
         
         Entity entity = ((Entity) stack.peek());

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageBinaryBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageBinaryBody.java?rev=721894&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageBinaryBody.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageBinaryBody.java Sun Nov 30 12:59:36 2008
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.james.mime4j.decoder.CodecUtil;
+import org.apache.james.mime4j.message.storage.Storage;
+
+/**
+ * Binary body backed by a
+ * {@link org.apache.james.mime4j.message.storage.Storage}
+ */
+class StorageBinaryBody extends AbstractBody implements BinaryBody {
+
+    private Storage storage = null;
+
+    public StorageBinaryBody(final Storage storage) {
+        this.storage = storage;
+    }
+
+    /**
+     * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
+     */
+    public InputStream getInputStream() throws IOException {
+        return storage.getInputStream();
+    }
+
+    /**
+     * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream,
+     *      Mode)
+     */
+    public void writeTo(OutputStream out, Mode mode) throws IOException {
+        if (out == null)
+            throw new IllegalArgumentException();
+
+        InputStream in = storage.getInputStream();
+        CodecUtil.copy(in, out);
+        in.close();
+    }
+
+    /**
+     * Deletes the Storage that holds the content of this binary body.
+     * 
+     * @see org.apache.james.mime4j.message.Disposable#dispose()
+     */
+    @Override
+    public void dispose() {
+        if (storage != null) {
+            storage.delete();
+            storage = null;
+        }
+    }
+
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageTextBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageTextBody.java?rev=721894&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageTextBody.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StorageTextBody.java Sun Nov 30 12:59:36 2008
@@ -0,0 +1,78 @@
+/****************************************************************
+ * 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.message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+
+import org.apache.james.mime4j.decoder.CodecUtil;
+import org.apache.james.mime4j.message.storage.Storage;
+
+/**
+ * Text body backed by a {@link org.apache.james.mime4j.message.storage.Storage}.
+ */
+class StorageTextBody extends AbstractBody implements TextBody {
+
+    private Storage storage;
+    private Charset charset;
+
+    public StorageTextBody(Storage storage, Charset charset) {
+        this.storage = storage;
+        this.charset = charset;
+    }
+
+    /**
+     * @see org.apache.james.mime4j.message.TextBody#getReader()
+     */
+    public Reader getReader() throws IOException {
+        return new InputStreamReader(storage.getInputStream(), charset);
+    }
+
+    /**
+     * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream,
+     *      Mode)
+     */
+    public void writeTo(OutputStream out, Mode mode) throws IOException {
+        if (out == null)
+            throw new IllegalArgumentException();
+
+        InputStream in = storage.getInputStream();
+        CodecUtil.copy(in, out);
+        in.close();
+    }
+
+    /**
+     * Deletes the Storage that holds the content of this text body.
+     * 
+     * @see org.apache.james.mime4j.message.Disposable#dispose()
+     */
+    @Override
+    public void dispose() {
+        if (storage != null) {
+            storage.delete();
+            storage = null;
+        }
+    }
+
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StringTextBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StringTextBody.java?rev=721894&view=auto
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StringTextBody.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/StringTextBody.java Sun Nov 30 12:59:36 2008
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.message;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+/**
+ * Text body backed by a <code>String</code>.
+ */
+class StringTextBody extends AbstractBody implements TextBody {
+
+    private final String text;
+    private final Charset charset;
+
+    public StringTextBody(final String text, Charset charset) {
+        this.text = text;
+        this.charset = charset;
+    }
+
+    /**
+     * @see org.apache.james.mime4j.message.TextBody#getReader()
+     */
+    public Reader getReader() throws IOException {
+        return new StringReader(text);
+    }
+
+    /**
+     * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream,
+     *      Mode)
+     */
+    public void writeTo(OutputStream out, Mode mode) throws IOException {
+        if (out == null)
+            throw new IllegalArgumentException();
+
+        Reader reader = new StringReader(text);
+        Writer writer = new OutputStreamWriter(out, charset);
+
+        char buffer[] = new char[1024];
+        while (true) {
+            int nChars = reader.read(buffer);
+            if (nChars == -1)
+                break;
+
+            writer.write(buffer, 0, nChars);
+        }
+
+        reader.close();
+        writer.flush();
+    }
+
+}

Modified: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java?rev=721894&r1=721893&r2=721894&view=diff
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java (original)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java Sun Nov 30 12:59:36 2008
@@ -20,12 +20,7 @@
 package org.apache.james.mime4j.message;
 
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.StringReader;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.james.mime4j.field.Field;
 
 import junit.framework.TestCase;
@@ -39,6 +34,8 @@
 public class MultipartFormTest extends TestCase {
 
     public void testMultipartFormContent() throws Exception {
+        BodyFactory bodyFactory = new BodyFactory();
+        
         Message message = new Message();
         Header header = new Header();
         header.addField(
@@ -51,17 +48,17 @@
         Header h1 = new Header();
         h1.addField(Field.parse("Content-Type: text/plain"));
         p1.setHeader(h1);
-        p1.setBody(new StringPart("this stuff"));
+        p1.setBody(bodyFactory.textBody("this stuff"));
         BodyPart p2 = new BodyPart();
         Header h2 = new Header();
         h2.addField(Field.parse("Content-Type: text/plain"));
         p2.setHeader(h2);
-        p2.setBody(new StringPart("that stuff"));
+        p2.setBody(bodyFactory.textBody("that stuff"));
         BodyPart p3 = new BodyPart();
         Header h3 = new Header();
         h3.addField(Field.parse("Content-Type: text/plain"));
         p3.setHeader(h3);
-        p3.setBody(new StringPart("all kind of stuff"));
+        p3.setBody(bodyFactory.textBody("all kind of stuff"));
 
         multipart.addBodyPart(p1);
         multipart.addBodyPart(p2);
@@ -89,38 +86,4 @@
         assertEquals(expected, s);
     }
     
-    public class StringPart extends AbstractBody implements TextBody {
-
-        private final String text;
-        private final String charset;
-        
-        public StringPart(final String text, String charset) {
-            super();
-            if (text == null) {
-                throw new IllegalArgumentException("Text may not be null");
-            }
-            if (charset == null) {
-                charset = "UTF-8";
-            }
-            this.text = text;
-            this.charset = charset;
-        }
-        
-        public StringPart(final String text) {
-            this(text, null);
-        }
-        
-        public Reader getReader() throws IOException {
-            return new StringReader(this.text);
-        }
-
-        public void writeTo(final OutputStream out, Mode mode) throws IOException {
-            if (out == null) {
-                throw new IllegalArgumentException("Output stream may not be null");
-            }
-            IOUtils.copy(getReader(), out, this.charset);
-        }
-        
-    }
-    
 }



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