You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mime4j-dev@james.apache.org by ol...@apache.org on 2011/01/17 17:20:54 UTC

svn commit: r1059973 - in /james/mime4j/branches/dom-api-refactoring: benchmark/src/main/java/org/apache/james/mime4j/ dom/src/main/java/org/apache/james/mime4j/dom/ dom/src/main/java/org/apache/james/mime4j/message/ dom/src/test/java/org/apache/james/...

Author: olegk
Date: Mon Jan 17 16:20:53 2011
New Revision: 1059973

URL: http://svn.apache.org/viewvc?rev=1059973&view=rev
Log:
Moved all copy / parse methods to MimeBuilder class

Added:
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java   (with props)
Removed:
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/BodyCopier.java
Modified:
    james/mime4j/branches/dom-api-refactoring/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java
    james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/CopyConstructorTest.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/ExampleMessagesRoundtripTest.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageCompleteMailTest.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageHeadlessParserTest.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageParserTest.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageTest.java
    james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageWriteToTest.java
    james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
    james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java

Modified: james/mime4j/branches/dom-api-refactoring/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java (original)
+++ james/mime4j/branches/dom-api-refactoring/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java Mon Jan 17 16:20:53 2011
@@ -26,7 +26,7 @@ import java.io.InputStream;
 
 import org.apache.james.mime4j.codec.CodecUtil;
 import org.apache.james.mime4j.dom.Header;
-import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.message.SimpleContentHandler;
 import org.apache.james.mime4j.parser.AbstractContentHandler;
 import org.apache.james.mime4j.parser.ContentHandler;
@@ -60,7 +60,7 @@ public class LongMultipartReadBench {
         System.out.println("No of repetitions: " + repetitions);
         System.out.println("Content length: " + content.length);
         System.out.println("Test: " + test.getClass().getSimpleName());
-        
+
         System.out.print("Warmup... ");
         long t0 = System.currentTimeMillis();
         while (System.currentTimeMillis() - t0 < 1500) {
@@ -171,7 +171,7 @@ public class LongMultipartReadBench {
             DefaultStorageProvider.setInstance(new MemoryStorageProvider());
 
             for (int i = 0; i < repetitions; i++) {
-                new MessageImpl(new ByteArrayInputStream(content));
+                MimeBuilder.parse(new ByteArrayInputStream(content));
             }
         }
     }

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java Mon Jan 17 16:20:53 2011
@@ -79,6 +79,16 @@ public interface Entity extends Disposab
     Body removeBody();
     
     /**
+     * Determines if the MIME type of this <code>Entity</code> is
+     * <code>multipart/*</code>. Since multipart-entities must have
+     * a boundary parameter in the <code>Content-Type</code> field this
+     * method returns <code>false</code> if no boundary exists.
+     * 
+     * @return <code>true</code> on match, <code>false</code> otherwise.
+     */
+    boolean isMultipart();
+    
+    /**
      * Determines the MIME type of this <code>Entity</code>. The MIME type
      * is derived by looking at the parent's Content-Type field if no
      * Content-Type field is set for this <code>Entity</code>.

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java Mon Jan 17 16:20:53 2011
@@ -22,11 +22,6 @@ package org.apache.james.mime4j.message;
 import java.util.Date;
 import java.util.Map;
 
-import org.apache.james.mime4j.dom.Body;
-import org.apache.james.mime4j.dom.Entity;
-import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.dom.SingleBody;
 import org.apache.james.mime4j.dom.field.ContentDispositionField;
 import org.apache.james.mime4j.dom.field.ContentTransferEncodingField;
 import org.apache.james.mime4j.dom.field.ContentTypeField;
@@ -46,34 +41,6 @@ public class BodyPart extends EntityBase
     public BodyPart() {
     }
 
-    /**
-     * Creates a new <code>BodyPart</code> from the specified
-     * <code>BodyPart</code>. The <code>BodyPart</code> instance is initialized
-     * with copies of header and body of the specified <code>BodyPart</code>.
-     * The parent entity of the new body part is <code>null</code>.
-     * 
-     * @param other
-     *            body part to copy.
-     * @throws UnsupportedOperationException
-     *             if <code>other</code> contains a {@link SingleBody} that
-     *             does not support the {@link SingleBody#copy() copy()}
-     *             operation.
-     * @throws IllegalArgumentException
-     *             if <code>other</code> contains a <code>Body</code> that
-     *             is neither a {@link Message}, {@link Multipart} or
-     *             {@link SingleBody}.
-     */
-    public BodyPart(Entity other) {
-        if (other.getHeader() != null) {
-            setHeader(new HeaderImpl(other.getHeader()));
-        }
-
-        if (other.getBody() != null) {
-            Body bodyCopy = BodyCopier.copy(other.getBody());
-            setBody(bodyCopy);
-        }
-    }
-
 	@Override
 	protected String newUniqueBoundary() {
 		return MimeUtil.createUniqueBoundary();

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java Mon Jan 17 16:20:53 2011
@@ -43,7 +43,7 @@ import org.apache.james.mime4j.util.Byte
  * A <code>ContentHandler</code> for building an <code>Entity</code> to be
  * used in conjunction with a {@link org.apache.james.mime4j.parser.MimeStreamParser}.
  */
-public class EntityBuilder implements ContentHandler {
+class EntityBuilder implements ContentHandler {
 
     private final Entity entity;
     private final BodyFactory bodyFactory;

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java Mon Jan 17 16:20:53 2011
@@ -19,19 +19,6 @@
 
 package org.apache.james.mime4j.message;
 
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.MimeIOException;
-import org.apache.james.mime4j.codec.DecodeMonitor;
-import org.apache.james.mime4j.dom.Header;
-import org.apache.james.mime4j.dom.field.Field;
-import org.apache.james.mime4j.field.DefaultFieldParser;
-import org.apache.james.mime4j.parser.AbstractContentHandler;
-import org.apache.james.mime4j.parser.MimeStreamParser;
-import org.apache.james.mime4j.stream.RawField;
-
 /**
  * The header of an entity (see RFC 2045).
  */
@@ -43,50 +30,4 @@ public class HeaderImpl extends HeaderBa
     public HeaderImpl() {
     }
 
-    /**
-     * Creates a new <code>Header</code> from the specified
-     * <code>Header</code>. The <code>Header</code> instance is initialized
-     * with a copy of the list of {@link Field}s of the specified
-     * <code>Header</code>. The <code>Field</code> objects are not copied
-     * because they are immutable and can safely be shared between headers.
-     * 
-     * @param other
-     *            header to copy.
-     */
-    public HeaderImpl(Header other) {
-        for (Field otherField : other.getFields()) {
-            addField(otherField);
-        }
-    }
-
-    /**
-     * Creates a new <code>Header</code> from the specified stream.
-     * 
-     * @param is the stream to read the header from.
-     * 
-     * @throws IOException on I/O errors.
-     * @throws MimeIOException on MIME protocol violations.
-     */
-    public HeaderImpl(
-            final InputStream is,
-            final DecodeMonitor monitor) throws IOException, MimeIOException {
-        final MimeStreamParser parser = new MimeStreamParser();
-        parser.setContentHandler(new AbstractContentHandler() {
-            @Override
-            public void endHeader() {
-                parser.stop();
-            }
-            @Override
-            public void field(RawField field) throws MimeException {
-                Field parsedField = DefaultFieldParser.parse(field.getRaw(), monitor); 
-                addField(parsedField);
-            }
-        });
-        try {
-            parser.parse(is);
-        } catch (MimeException ex) {
-            throw new MimeIOException(ex);
-        }
-    }
-
 }

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java Mon Jan 17 16:20:53 2011
@@ -34,12 +34,18 @@ public class MessageBuilderImpl extends 
 
     @Override
     public Message newMessage(Message source) {
-        return new MessageImpl(source);
+        return MimeBuilder.copy(source);
     }
 
     @Override
     public Message parse(InputStream source) throws MimeException, IOException {
-        return new MessageImpl(source, mimeEntityConfig, storageProvider, mutableBodyDescriptorFactory, decodeMonitor, contentDecoding, flatMode);
+        return MimeBuilder.parse(source, 
+                mimeEntityConfig, 
+                storageProvider, 
+                mutableBodyDescriptorFactory, 
+                decodeMonitor, 
+                contentDecoding, 
+                flatMode);
     }
 
     @Override

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java Mon Jan 17 16:20:53 2011
@@ -20,20 +20,12 @@
 package org.apache.james.mime4j.message;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Map;
 import java.util.TimeZone;
 
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.MimeIOException;
-import org.apache.james.mime4j.codec.DecodeMonitor;
-import org.apache.james.mime4j.dom.Body;
-import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.dom.SingleBody;
 import org.apache.james.mime4j.dom.address.Address;
 import org.apache.james.mime4j.dom.address.Mailbox;
 import org.apache.james.mime4j.dom.field.AddressListField;
@@ -48,20 +40,10 @@ import org.apache.james.mime4j.dom.field
 import org.apache.james.mime4j.field.ContentTransferEncodingFieldImpl;
 import org.apache.james.mime4j.field.ContentTypeFieldImpl;
 import org.apache.james.mime4j.field.Fields;
-import org.apache.james.mime4j.parser.MimeStreamParser;
-import org.apache.james.mime4j.storage.DefaultStorageProvider;
-import org.apache.james.mime4j.storage.StorageProvider;
-import org.apache.james.mime4j.stream.MimeEntityConfig;
-import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory;
 import org.apache.james.mime4j.util.MimeUtil;
 
 /**
- * Represents a MIME message. The following code parses a stream into a
- * <code>Message</code> object.
- * 
- * <pre>
- * Message msg = new Message(new FileInputStream(&quot;mime.msg&quot;));
- * </pre>
+ * Represents a MIME message. 
  */
 public class MessageImpl extends MessageBase {
 
@@ -72,146 +54,6 @@ public class MessageImpl extends Message
     }
 
     /**
-     * Creates a new <code>Message</code> from the specified
-     * <code>Message</code>. The <code>Message</code> instance is
-     * initialized with copies of header and body of the specified
-     * <code>Message</code>. The parent entity of the new message is
-     * <code>null</code>.
-     * 
-     * @param other
-     *            message to copy.
-     * @throws UnsupportedOperationException
-     *             if <code>other</code> contains a {@link SingleBody} that
-     *             does not support the {@link SingleBody#copy() copy()}
-     *             operation.
-     * @throws IllegalArgumentException
-     *             if <code>other</code> contains a <code>Body</code> that
-     *             is neither a {@link MessageImpl}, {@link Multipart} or
-     *             {@link SingleBody}.
-     */
-    public MessageImpl(Message other) {
-        if (other.getHeader() != null) {
-            setHeader(new HeaderImpl(other.getHeader()));
-        }
-
-        if (other.getBody() != null) {
-            Body bodyCopy = BodyCopier.copy(other.getBody());
-            setBody(bodyCopy);
-        }
-    }
-
-    /**
-     * Parses the specified MIME message stream into a <code>Message</code>
-     * instance.
-     * 
-     * @param is
-     *            the stream to parse.
-     * @throws IOException
-     *             on I/O errors.
-     * @throws MimeIOException
-     *             on MIME protocol violations.
-     */
-    public MessageImpl(InputStream is) throws IOException, MimeIOException {
-        this(is, null, DefaultStorageProvider.getInstance());
-    }
-
-    /**
-     * Parses the specified MIME message stream into a <code>Message</code>
-     * instance using given {@link MimeEntityConfig}.
-     * 
-     * @param is
-     *            the stream to parse.
-     * @throws IOException
-     *             on I/O errors.
-     * @throws MimeIOException
-     *             on MIME protocol violations.
-     */
-    public MessageImpl(InputStream is, MimeEntityConfig config) throws IOException,
-            MimeIOException {
-        this(is, config, DefaultStorageProvider.getInstance());
-    }
-
-    /**
-     * Parses the specified MIME message stream into a <code>Message</code>
-     * instance using given {@link MimeEntityConfig} and {@link StorageProvider}.
-     * 
-     * @param is
-     *            the stream to parse.
-     * @param config
-     *            {@link MimeEntityConfig} to use.
-     * @param storageProvider
-     *            {@link StorageProvider} to use for storing text and binary
-     *            message bodies.
-     * @param bodyDescFactory
-     *            {@link MutableBodyDescriptorFactory} to use for creating body descriptors.
-     * @throws IOException
-     *             on I/O errors.
-     * @throws MimeIOException
-     *             on MIME protocol violations.
-     */
-    public MessageImpl(
-            final InputStream is, 
-            final MimeEntityConfig config,
-            final StorageProvider storageProvider, 
-            final MutableBodyDescriptorFactory bodyDescFactory,
-            final DecodeMonitor monitor) throws IOException, MimeIOException {
-        this(is, config, storageProvider, bodyDescFactory, monitor, true, false);
-    }
-    
-    /**
-     * Parses the specified MIME message stream into a <code>Message</code>
-     * instance using given {@link MimeEntityConfig} and {@link StorageProvider}.
-     * 
-     * @param is
-     *            the stream to parse.
-     * @param config
-     *            {@link MimeEntityConfig} to use.
-     * @param storageProvider
-     *            {@link StorageProvider} to use for storing text and binary
-     *            message bodies.
-     * @param bodyDescFactory
-     *            {@link MutableBodyDescriptorFactory} to use for creating body descriptors.
-     * @throws IOException
-     *             on I/O errors.
-     * @throws MimeIOException
-     *             on MIME protocol violations.
-     */
-    public MessageImpl(
-            final InputStream is, 
-            final MimeEntityConfig config,
-            final StorageProvider storageProvider, 
-            final MutableBodyDescriptorFactory bodyDescFactory,
-            final DecodeMonitor monitor,
-            boolean contentDecoding,
-            boolean flatMode) throws IOException, MimeIOException {
-        try {
-            DecodeMonitor mon = monitor != null ? monitor : DecodeMonitor.SILENT;
-            MimeStreamParser parser = new MimeStreamParser(config, bodyDescFactory, mon);
-            parser.setContentHandler(new EntityBuilder(this, storageProvider, mon));
-            parser.setContentDecoding(contentDecoding);
-            if (flatMode) parser.setFlat(true);
-            parser.parse(is);
-        } catch (MimeException e) {
-            throw new MimeIOException(e);
-        }
-    }
-    
-    public MessageImpl(
-            final InputStream is, 
-            final MimeEntityConfig config,
-            final StorageProvider storageProvider,
-            final MutableBodyDescriptorFactory bodyDescFactory) throws IOException, MimeIOException {
-        this(is, config, storageProvider, bodyDescFactory, null);
-    }
-
-    public MessageImpl(
-            final InputStream is, 
-            final MimeEntityConfig config,
-            final StorageProvider storageProvider) throws IOException, MimeIOException {
-        this(is, config, storageProvider, null, null);
-    }
-
-    /**
      * @see org.apache.james.mime4j.dom.Message#writeTo(java.io.OutputStream)
      */
     public void writeTo(OutputStream out) throws IOException {

Added: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java?rev=1059973&view=auto
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java (added)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java Mon Jan 17 16:20:53 2011
@@ -0,0 +1,340 @@
+/****************************************************************
+ * 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 org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.MimeIOException;
+import org.apache.james.mime4j.codec.DecodeMonitor;
+import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.dom.Disposable;
+import org.apache.james.mime4j.dom.Entity;
+import org.apache.james.mime4j.dom.Header;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.dom.SingleBody;
+import org.apache.james.mime4j.dom.field.Field;
+import org.apache.james.mime4j.field.DefaultFieldParser;
+import org.apache.james.mime4j.parser.AbstractContentHandler;
+import org.apache.james.mime4j.parser.MimeStreamParser;
+import org.apache.james.mime4j.storage.DefaultStorageProvider;
+import org.apache.james.mime4j.storage.StorageProvider;
+import org.apache.james.mime4j.stream.MimeEntityConfig;
+import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory;
+import org.apache.james.mime4j.stream.RawField;
+
+/**
+ * Utility class for copying message and parsing message elements.
+ */
+public final class MimeBuilder {
+
+    private MimeBuilder() {
+    }
+
+    /**
+     * Creates a new <code>Header</code> from the specified
+     * <code>Header</code>. The <code>Header</code> instance is initialized
+     * with a copy of the list of {@link Field}s of the specified
+     * <code>Header</code>. The <code>Field</code> objects are not copied
+     * because they are immutable and can safely be shared between headers.
+     * 
+     * @param other
+     *            header to copy.
+     */
+    public static Header copy(Header other) {
+        HeaderImpl copy = new HeaderImpl();
+        for (Field otherField : other.getFields()) {
+            copy.addField(otherField);
+        }
+        return copy;
+    }
+
+    /**
+     * Creates a new <code>BodyPart</code> from the specified
+     * <code>Entity</code>. The <code>BodyPart</code> instance is initialized
+     * with copies of header and body of the specified <code>Entity</code>.
+     * The parent entity of the new body part is <code>null</code>.
+     * 
+     * @param other
+     *            body part to copy.
+     * @throws UnsupportedOperationException
+     *             if <code>other</code> contains a {@link SingleBody} that
+     *             does not support the {@link SingleBody#copy() copy()}
+     *             operation.
+     * @throws IllegalArgumentException
+     *             if <code>other</code> contains a <code>Body</code> that
+     *             is neither a {@link Message}, {@link Multipart} or
+     *             {@link SingleBody}.
+     */
+    public static BodyPart copy(Entity other) {
+        BodyPart copy = new BodyPart(); 
+        if (other.getHeader() != null) {
+            copy.setHeader(copy(other.getHeader()));
+        }
+        if (other.getBody() != null) {
+            copy.setBody(copy(other.getBody()));
+        }
+        return copy;
+    }
+
+    /**
+     * Creates a new <code>Multipart</code> from the specified
+     * <code>Multipart</code>. The <code>Multipart</code> instance is
+     * initialized with copies of preamble, epilogue, sub type and the list of
+     * body parts of the specified <code>Multipart</code>. The parent entity
+     * of the new multipart is <code>null</code>.
+     * 
+     * @param other
+     *            multipart to copy.
+     * @throws UnsupportedOperationException
+     *             if <code>other</code> contains a {@link SingleBody} that
+     *             does not support the {@link SingleBody#copy() copy()}
+     *             operation.
+     * @throws IllegalArgumentException
+     *             if <code>other</code> contains a <code>Body</code> that
+     *             is neither a {@link Message}, {@link Multipart} or
+     *             {@link SingleBody}.
+     */
+    public static Multipart copy(Multipart other) {
+        MultipartImpl copy = new MultipartImpl(other.getSubType());
+        for (Entity otherBodyPart : other.getBodyParts()) {
+            copy.addBodyPart(copy(otherBodyPart));
+        }
+        copy.setPreamble(other.getPreamble());
+        copy.setEpilogue(other.getEpilogue());
+        return copy;
+    }
+
+    
+    /**
+     * Returns a copy of the given {@link Body} that can be used (and modified)
+     * independently of the original. The copy should be
+     * {@link Disposable#dispose() disposed of} when it is no longer needed.
+     * <p>
+     * The {@link Body#getParent() parent} of the returned copy is
+     * <code>null</code>, that is, the copy is detached from the parent
+     * entity of the original.
+     * 
+     * @param body
+     *            body to copy.
+     * @return a copy of the given body.
+     * @throws UnsupportedOperationException
+     *             if <code>body</code> is an instance of {@link SingleBody}
+     *             that does not support the {@link SingleBody#copy() copy()}
+     *             operation (or contains such a <code>SingleBody</code>).
+     * @throws IllegalArgumentException
+     *             if <code>body</code> is <code>null</code> or
+     *             <code>body</code> is a <code>Body</code> that is neither
+     *             a {@link MessageImpl}, {@link Multipart} or {@link SingleBody}
+     *             (or contains such a <code>Body</code>).
+     */
+    public static Body copy(Body body) {
+        if (body == null)
+            throw new IllegalArgumentException("Body is null");
+
+        if (body instanceof Message)
+            return copy((Message) body);
+
+        if (body instanceof Multipart)
+            return copy((Multipart) body);
+
+        if (body instanceof SingleBody)
+            return ((SingleBody) body).copy();
+
+        throw new IllegalArgumentException("Unsupported body class");
+    }
+
+    /**
+     * Creates a new <code>Message</code> from the specified
+     * <code>Message</code>. The <code>Message</code> instance is
+     * initialized with copies of header and body of the specified
+     * <code>Message</code>. The parent entity of the new message is
+     * <code>null</code>.
+     * 
+     * @param other
+     *            message to copy.
+     * @throws UnsupportedOperationException
+     *             if <code>other</code> contains a {@link SingleBody} that
+     *             does not support the {@link SingleBody#copy() copy()}
+     *             operation.
+     * @throws IllegalArgumentException
+     *             if <code>other</code> contains a <code>Body</code> that
+     *             is neither a {@link MessageImpl}, {@link Multipart} or
+     *             {@link SingleBody}.
+     */
+    public static Message copy(Message other) {
+        MessageImpl copy = new MessageImpl();
+        if (other.getHeader() != null) {
+            copy.setHeader(copy(other.getHeader()));
+        }
+        if (other.getBody() != null) {
+            copy.setBody(copy(other.getBody()));
+        }
+        return copy;
+    }
+    
+    /**
+     * Creates a new <code>Header</code> from the specified stream.
+     * 
+     * @param is the stream to read the header from.
+     * 
+     * @throws IOException on I/O errors.
+     * @throws MimeIOException on MIME protocol violations.
+     */
+    public static Header parse(
+            final InputStream is,
+            final DecodeMonitor monitor) throws IOException, MimeIOException {
+        final HeaderImpl header = new HeaderImpl();
+        final MimeStreamParser parser = new MimeStreamParser();
+        parser.setContentHandler(new AbstractContentHandler() {
+            @Override
+            public void endHeader() {
+                parser.stop();
+            }
+            @Override
+            public void field(RawField field) throws MimeException {
+                Field parsedField = DefaultFieldParser.parse(field.getRaw(), monitor); 
+                header.addField(parsedField);
+            }
+        });
+        try {
+            parser.parse(is);
+        } catch (MimeException ex) {
+            throw new MimeIOException(ex);
+        }
+        return header;
+    }
+
+    /**
+     * Parses the specified MIME message stream into a <code>Message</code>
+     * instance using given {@link MimeEntityConfig} and {@link StorageProvider}.
+     * 
+     * @param is
+     *            the stream to parse.
+     * @param config
+     *            {@link MimeEntityConfig} to use.
+     * @param storageProvider
+     *            {@link StorageProvider} to use for storing text and binary
+     *            message bodies.
+     * @param bodyDescFactory
+     *            {@link MutableBodyDescriptorFactory} to use for creating body descriptors.
+     * @throws IOException
+     *             on I/O errors.
+     * @throws MimeIOException
+     *             on MIME protocol violations.
+     */
+    public static Message parse(
+            final InputStream is, 
+            final MimeEntityConfig config,
+            final StorageProvider storageProvider, 
+            final MutableBodyDescriptorFactory bodyDescFactory,
+            final DecodeMonitor monitor,
+            boolean contentDecoding,
+            boolean flatMode) throws IOException, MimeIOException {
+        try {
+            MessageImpl message = new MessageImpl();
+            DecodeMonitor mon = monitor != null ? monitor : DecodeMonitor.SILENT;
+            MimeStreamParser parser = new MimeStreamParser(config, bodyDescFactory, mon);
+            parser.setContentHandler(new EntityBuilder(message, storageProvider, mon));
+            parser.setContentDecoding(contentDecoding);
+            if (flatMode) parser.setFlat(true);
+            parser.parse(is);
+            return message;
+        } catch (MimeException e) {
+            throw new MimeIOException(e);
+        }
+    }
+
+    /**
+     * Parses the specified MIME message stream into a <code>Message</code>
+     * instance using given {@link MimeEntityConfig} and {@link StorageProvider}.
+     * 
+     * @param is
+     *            the stream to parse.
+     * @param config
+     *            {@link MimeEntityConfig} to use.
+     * @param storageProvider
+     *            {@link StorageProvider} to use for storing text and binary
+     *            message bodies.
+     * @param bodyDescFactory
+     *            {@link MutableBodyDescriptorFactory} to use for creating body descriptors.
+     * @throws IOException
+     *             on I/O errors.
+     * @throws MimeIOException
+     *             on MIME protocol violations.
+     */
+    public static Message parse(
+            final InputStream is, 
+            final MimeEntityConfig config,
+            final StorageProvider storageProvider, 
+            final MutableBodyDescriptorFactory bodyDescFactory,
+            final DecodeMonitor monitor) throws IOException, MimeIOException {
+        return parse(is, config, storageProvider, bodyDescFactory, monitor, true, false);
+    }
+    
+    public static Message parse(
+            final InputStream is, 
+            final MimeEntityConfig config,
+            final StorageProvider storageProvider,
+            final MutableBodyDescriptorFactory bodyDescFactory) throws IOException, MimeIOException {
+        return parse(is, config, storageProvider, bodyDescFactory, null);
+    }
+
+    public static Message parse(
+            final InputStream is, 
+            final MimeEntityConfig config,
+            final StorageProvider storageProvider) throws IOException, MimeIOException {
+        return parse(is, config, storageProvider, null, null);
+    }
+
+    /**
+     * Parses the specified MIME message stream into a <code>Message</code>
+     * instance.
+     * 
+     * @param is
+     *            the stream to parse.
+     * @throws IOException
+     *             on I/O errors.
+     * @throws MimeIOException
+     *             on MIME protocol violations.
+     */
+    public static Message parse(InputStream is) throws IOException, MimeIOException {
+        return parse(is, null, DefaultStorageProvider.getInstance());
+    }
+
+    /**
+     * Parses the specified MIME message stream into a <code>Message</code>
+     * instance using given {@link MimeEntityConfig}.
+     * 
+     * @param is
+     *            the stream to parse.
+     * @throws IOException
+     *             on I/O errors.
+     * @throws MimeIOException
+     *             on MIME protocol violations.
+     */
+    public static Message parse(InputStream is, MimeEntityConfig config) throws IOException,
+            MimeIOException {
+        return parse(is, config, DefaultStorageProvider.getInstance());
+    }
+    
+}

Propchange: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java Mon Jan 17 16:20:53 2011
@@ -19,10 +19,6 @@
 
 package org.apache.james.mime4j.message;
 
-import org.apache.james.mime4j.dom.Entity;
-import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.dom.SingleBody;
 import org.apache.james.mime4j.util.ByteSequence;
 import org.apache.james.mime4j.util.ContentUtil;
 
@@ -55,45 +51,6 @@ public class MultipartImpl extends Multi
         epilogueComputed = true;
     }
 
-    /**
-     * Creates a new <code>Multipart</code> from the specified
-     * <code>Multipart</code>. The <code>Multipart</code> instance is
-     * initialized with copies of preamble, epilogue, sub type and the list of
-     * body parts of the specified <code>Multipart</code>. The parent entity
-     * of the new multipart is <code>null</code>.
-     * 
-     * @param other
-     *            multipart to copy.
-     * @throws UnsupportedOperationException
-     *             if <code>other</code> contains a {@link SingleBody} that
-     *             does not support the {@link SingleBody#copy() copy()}
-     *             operation.
-     * @throws IllegalArgumentException
-     *             if <code>other</code> contains a <code>Body</code> that
-     *             is neither a {@link Message}, {@link Multipart} or
-     *             {@link SingleBody}.
-     */
-    public MultipartImpl(Multipart other) {
-    	super(other.getSubType());
-
-    	for (Entity otherBodyPart : other.getBodyParts()) {
-    		Entity bodyPartCopy = new BodyPart(otherBodyPart);
-            addBodyPart(bodyPartCopy);
-        }
-
-    	if (other instanceof MultipartImpl) {
-	        preamble = ((MultipartImpl) other).preamble;
-	        epilogue = ((MultipartImpl) other).epilogue;
-            preambleStrCache = ((MultipartImpl) other).preambleStrCache;
-            epilogueStrCache = ((MultipartImpl) other).epilogueStrCache;
-            preambleComputed = ((MultipartImpl) other).preambleComputed;
-            epilogueComputed = ((MultipartImpl) other).epilogueComputed;
-    	} else {
-    		setPreamble(other.getPreamble());
-    		setEpilogue(other.getEpilogue());
-    	}
-    }
-
     // package private for now; might become public someday
     public ByteSequence getPreambleRaw() {
         return preamble;

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/CopyConstructorTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/CopyConstructorTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/CopyConstructorTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/CopyConstructorTest.java Mon Jan 17 16:20:53 2011
@@ -32,6 +32,7 @@ import org.apache.james.mime4j.message.B
 import org.apache.james.mime4j.message.BodyPart;
 import org.apache.james.mime4j.message.HeaderImpl;
 import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.message.MultipartImpl;
 
 import junit.framework.TestCase;
@@ -41,7 +42,7 @@ public class CopyConstructorTest extends
     public void testCopyEmptyMessage() throws Exception {
         MessageImpl original = new MessageImpl();
 
-        MessageImpl copy = new MessageImpl(original);
+        Message copy = MimeBuilder.copy(original);
 
         assertNull(copy.getHeader());
         assertNull(copy.getBody());
@@ -58,7 +59,7 @@ public class CopyConstructorTest extends
         original.setBody(body);
         original.setParent(parent);
 
-        MessageImpl copy = new MessageImpl(original);
+        Message copy = MimeBuilder.copy(original);
 
         assertNotNull(copy.getHeader());
         assertNotSame(header, copy.getHeader());
@@ -74,7 +75,7 @@ public class CopyConstructorTest extends
     public void testCopyEmptyBodyPart() throws Exception {
         BodyPart original = new BodyPart();
 
-        BodyPart copy = new BodyPart(original);
+        BodyPart copy = MimeBuilder.copy(original);
 
         assertNull(copy.getHeader());
         assertNull(copy.getBody());
@@ -91,7 +92,7 @@ public class CopyConstructorTest extends
         original.setBody(body);
         original.setParent(parent);
 
-        BodyPart copy = new BodyPart(original);
+        BodyPart copy = MimeBuilder.copy(original);
 
         assertNotNull(copy.getHeader());
         assertNotSame(header, copy.getHeader());
@@ -107,7 +108,7 @@ public class CopyConstructorTest extends
     public void testCopyEmptyMultipart() throws Exception {
         Multipart original = new MultipartImpl("mixed");
 
-        Multipart copy = new MultipartImpl(original);
+        Multipart copy = MimeBuilder.copy(original);
 
         assertSame(original.getPreamble(), copy.getPreamble());
         assertSame(original.getEpilogue(), copy.getEpilogue());
@@ -126,7 +127,7 @@ public class CopyConstructorTest extends
         original.setParent(parent);
         original.addBodyPart(bodyPart);
 
-        Multipart copy = new MultipartImpl(original);
+        Multipart copy = MimeBuilder.copy(original);
 
         assertSame(original.getPreamble(), copy.getPreamble());
         assertSame(original.getEpilogue(), copy.getEpilogue());
@@ -153,7 +154,7 @@ public class CopyConstructorTest extends
         original.setHeader(new HeaderImpl());
         original.setBody(multipart);
 
-        MessageImpl copy = new MessageImpl(original);
+        Message copy = MimeBuilder.copy(original);
 
         Multipart multipartCopy = (Multipart) copy.getBody();
         List<Entity> bodyParts = multipartCopy.getBodyParts();
@@ -179,7 +180,7 @@ public class CopyConstructorTest extends
         original.addField(f2);
         original.addField(f3);
 
-        Header copy = new HeaderImpl(original);
+        Header copy = MimeBuilder.copy(original);
 
         // copy must have same fields as original
         assertEquals(Arrays.asList(f1, f2, f3), copy.getFields());

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/ExampleMessagesRoundtripTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/ExampleMessagesRoundtripTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/ExampleMessagesRoundtripTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/ExampleMessagesRoundtripTest.java Mon Jan 17 16:20:53 2011
@@ -35,7 +35,7 @@ import junit.framework.TestSuite;
 
 import org.apache.james.mime4j.codec.CodecUtil;
 import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.stream.MimeEntityConfig;
 
 /**
@@ -58,7 +58,7 @@ public class ExampleMessagesRoundtripTes
             config.setMalformedHeaderStartsBody(true);
         }
         config.setMaxLineLen(-1);
-        Message inputMessage = new MessageImpl(url.openStream(), config);
+        Message inputMessage = MimeBuilder.parse(url.openStream(), config);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         inputMessage.writeTo(out);
         

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageCompleteMailTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageCompleteMailTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageCompleteMailTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageCompleteMailTest.java Mon Jan 17 16:20:53 2011
@@ -25,7 +25,7 @@ import junit.framework.TestCase;
 
 import org.apache.james.mime4j.ExampleMail;
 import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 
 public class MessageCompleteMailTest extends TestCase {
 
@@ -40,22 +40,22 @@ public class MessageCompleteMailTest ext
     }
     
     public void testMultipartAlternative() throws Exception {
-        MessageImpl message = createMessage(ExampleMail.MIME_MULTIPART_ALTERNATIVE_BYTES);
+        Message message = createMessage(ExampleMail.MIME_MULTIPART_ALTERNATIVE_BYTES);
         assertTrue("Should be a multipart/alternative mail", message.isMultipart());
         Multipart part = (Multipart)message.getBody();
         assertEquals("alternative", part.getSubType());
     }    
     
     public void testMultipartMixed() throws Exception {
-        MessageImpl message = createMessage(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTES);
+        Message message = createMessage(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTES);
         assertTrue("Should be a multipart/mixed mail", message.isMultipart());
         Multipart part = (Multipart)message.getBody();
         assertEquals("mixed", part.getSubType());
     }
 
-    private MessageImpl createMessage(byte[] octets) throws Exception {
+    private Message createMessage(byte[] octets) throws Exception {
         ByteArrayInputStream in = new ByteArrayInputStream(octets);
-        MessageImpl message = new MessageImpl(in);
+        Message message = MimeBuilder.parse(in);
         return message;
     }
 }

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageHeadlessParserTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageHeadlessParserTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageHeadlessParserTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageHeadlessParserTest.java Mon Jan 17 16:20:53 2011
@@ -28,7 +28,7 @@ import org.apache.james.mime4j.dom.Multi
 import org.apache.james.mime4j.dom.TextBody;
 import org.apache.james.mime4j.dom.field.ContentTypeField;
 import org.apache.james.mime4j.dom.field.FieldName;
-import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.stream.MimeEntityConfig;
 
 public class MessageHeadlessParserTest extends TestCase {
@@ -44,7 +44,7 @@ public class MessageHeadlessParserTest e
 
 		MimeEntityConfig mimeEntityConfig = new MimeEntityConfig();
 		mimeEntityConfig.setMalformedHeaderStartsBody(true);
-		MessageImpl message = new MessageImpl(new ByteArrayInputStream(headlessContent
+		Message message = MimeBuilder.parse(new ByteArrayInputStream(headlessContent
 				.getBytes("UTF-8")), mimeEntityConfig);
 		assertEquals("text/plain", message.getMimeType());
 		assertEquals(1, message.getHeader().getFields().size());
@@ -62,7 +62,7 @@ public class MessageHeadlessParserTest e
 
 		MimeEntityConfig mimeEntityConfig = new MimeEntityConfig();
 		mimeEntityConfig.setMalformedHeaderStartsBody(true);
-		MessageImpl message = new MessageImpl(new ByteArrayInputStream(headlessContent
+		Message message = MimeBuilder.parse(new ByteArrayInputStream(headlessContent
 				.getBytes("UTF-8")), mimeEntityConfig);
 		assertEquals("text/plain", message.getMimeType());
 		assertEquals(0, message.getHeader().getFields().size());
@@ -89,7 +89,7 @@ public class MessageHeadlessParserTest e
 
 		MimeEntityConfig mimeEntityConfig = new MimeEntityConfig();
 		mimeEntityConfig.setHeadlessParsing(contentType);
-		MessageImpl message = new MessageImpl(new ByteArrayInputStream(headlessContent
+		Message message = MimeBuilder.parse(new ByteArrayInputStream(headlessContent
 				.getBytes("UTF-8")), mimeEntityConfig);
 		assertEquals("multipart/form-data", message.getMimeType());
 		assertEquals(1, message.getHeader().getFields().size());

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageParserTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageParserTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageParserTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageParserTest.java Mon Jan 17 16:20:53 2011
@@ -43,6 +43,7 @@ import org.apache.james.mime4j.dom.TextB
 import org.apache.james.mime4j.dom.field.Field;
 import org.apache.james.mime4j.field.FieldsTest;
 import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.stream.MimeEntityConfig;
 import org.apache.james.mime4j.util.CharsetUtil;
 
@@ -101,7 +102,7 @@ public class MessageParserTest extends T
             config.setMalformedHeaderStartsBody(true);
         }
         config.setMaxLineLen(-1);
-        MessageImpl m = new MessageImpl(url.openStream(), config);
+        Message m = MimeBuilder.parse(url.openStream(), config);
         
         String s = url.toString();
         String prefix = s.substring(0, s.lastIndexOf('.'));

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageTest.java Mon Jan 17 16:20:53 2011
@@ -44,6 +44,7 @@ import org.apache.james.mime4j.field.add
 import org.apache.james.mime4j.message.BodyPart;
 import org.apache.james.mime4j.message.HeaderImpl;
 import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.message.MultipartImpl;
 
 public class MessageTest extends TestCase {
@@ -132,7 +133,7 @@ public class MessageTest extends TestCas
     public void testWriteTo() throws Exception {
         byte[] inputByte = getRawMessageAsByteArray();
 
-        Message m = new MessageImpl(new ByteArrayInputStream(inputByte));
+        Message m = MimeBuilder.parse(new ByteArrayInputStream(inputByte));
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 
         m.writeTo(out);
@@ -154,7 +155,7 @@ public class MessageTest extends TestCas
 
         byte[] inputByte = getRawMessageAsByteArray();
 
-        MessageImpl m = new MessageImpl(new ByteArrayInputStream(inputByte));
+        Message m = MimeBuilder.parse(new ByteArrayInputStream(inputByte));
         m.getHeader().addField(DefaultFieldParser.parse(testheader));
 
         assertEquals("header added", m.getHeader().getField(headerName)

Modified: james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageWriteToTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageWriteToTest.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageWriteToTest.java (original)
+++ james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MessageWriteToTest.java Mon Jan 17 16:20:53 2011
@@ -23,7 +23,7 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 
 import org.apache.james.mime4j.ExampleMail;
-import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 
 import junit.framework.TestCase;
 
@@ -40,7 +40,7 @@ public class MessageWriteToTest extends 
     }
     
     public void testSimpleMail() throws Exception {
-        MessageImpl message = createMessage(ExampleMail.RFC822_SIMPLE_BYTES);
+        Message message = createMessage(ExampleMail.RFC822_SIMPLE_BYTES);
         assertFalse("Not multipart", message.isMultipart());
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         message.writeTo(out);
@@ -58,7 +58,7 @@ public class MessageWriteToTest extends 
     }
     
     public void testBinaryAttachment() throws Exception {
-        MessageImpl message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES);
+        Message message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES);
         assertTrue("Is multipart", message.isMultipart());
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         message.writeTo(out);
@@ -66,7 +66,7 @@ public class MessageWriteToTest extends 
     }
     
     public void testBinaryAttachmentNoPreamble() throws Exception {
-        MessageImpl message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_NOPREAMBLE_BYTES);
+        Message message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_NOPREAMBLE_BYTES);
         assertTrue("Is multipart", message.isMultipart());
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         message.writeTo(out);
@@ -74,16 +74,16 @@ public class MessageWriteToTest extends 
     }
     
     public void testBinaryAttachmentPreambleEpilogue() throws Exception {
-        MessageImpl message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_PREAMBLE_EPILOGUE_BYTES);
+        Message message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_PREAMBLE_EPILOGUE_BYTES);
         assertTrue("Is multipart", message.isMultipart());
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         message.writeTo(out);
         assertEquals(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_PREAMBLE_EPILOGUE_BYTES, out.toByteArray());
     }
     
-    private MessageImpl createMessage(byte[] octets) throws Exception {
+    private Message createMessage(byte[] octets) throws Exception {
         ByteArrayInputStream in = new ByteArrayInputStream(octets);
-        MessageImpl message = new MessageImpl(in);
+        Message message = MimeBuilder.parse(in);
         return message;
     }
 }

Modified: james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java (original)
+++ james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java Mon Jan 17 16:20:53 2011
@@ -34,6 +34,7 @@ import org.apache.james.mime4j.field.add
 import org.apache.james.mime4j.message.BodyFactory;
 import org.apache.james.mime4j.message.BodyPart;
 import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 import org.apache.james.mime4j.message.MultipartImpl;
 import org.apache.james.mime4j.storage.DefaultStorageProvider;
 import org.apache.james.mime4j.storage.StorageProvider;
@@ -90,7 +91,7 @@ public class TransformMessage {
     private static Message transform(Message original) throws IOException, ParseException {
         // Create a copy of the template. The copy can be modified without
         // affecting the original.
-        MessageImpl message = new MessageImpl(original);
+        Message message = MimeBuilder.copy(original);
 
         // In this example we know we have a multipart message. Use
         // Message#isMultipart() if uncertain.

Modified: james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java?rev=1059973&r1=1059972&r2=1059973&view=diff
==============================================================================
--- james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java (original)
+++ james/mime4j/branches/dom-api-refactoring/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java Mon Jan 17 16:20:53 2011
@@ -44,6 +44,7 @@ import org.apache.james.mime4j.dom.Binar
 import org.apache.james.mime4j.dom.Body;
 import org.apache.james.mime4j.dom.Entity;
 import org.apache.james.mime4j.dom.Header;
+import org.apache.james.mime4j.dom.Message;
 import org.apache.james.mime4j.dom.Multipart;
 import org.apache.james.mime4j.dom.TextBody;
 import org.apache.james.mime4j.dom.address.Mailbox;
@@ -56,10 +57,11 @@ import org.apache.james.mime4j.dom.field
 import org.apache.james.mime4j.field.address.formatter.AddressFormatter;
 import org.apache.james.mime4j.message.BodyPart;
 import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MimeBuilder;
 
 /**
  * Displays a parsed Message in a window. The window will be divided into
- * two panels. The left panel displays the Message tree. Clicking on a 
+ * two panels. The left panel displays the Message tree. Clicking on a
  * node in the tree shows information on that node in the right panel.
  *
  * Some of this code have been copied from the Java tutorial's JTree section.
@@ -72,36 +74,36 @@ public class MessageTree extends JPanel 
     private JTree tree;
 
     /**
-     * Wraps an Object and associates it with a text. All message parts 
+     * Wraps an Object and associates it with a text. All message parts
      * (headers, bodies, multiparts, body parts) will be wrapped in
      * ObjectWrapper instances before they are added to the JTree instance.
      */
     public static class ObjectWrapper {
         private String text = "";
         private Object object = null;
-        
+
         public ObjectWrapper(String text, Object object) {
             this.text = text;
             this.object = object;
         }
-        
+
         @Override
         public String toString() {
             return text;
         }
-        
+
         public Object getObject() {
             return object;
         }
     }
-    
+
     /**
-     * Creates a new <code>MessageTree</code> instance displaying the 
+     * Creates a new <code>MessageTree</code> instance displaying the
      * specified <code>Message</code>.
-     * 
+     *
      * @param message the message to display.
      */
-    public MessageTree(MessageImpl message) {
+    public MessageTree(Message message) {
         super(new GridLayout(1,0));
 
         DefaultMutableTreeNode root = createNode(message);
@@ -128,17 +130,17 @@ public class MessageTree extends JPanel 
         splitPane.setPreferredSize(new Dimension(750, 500));
 
         add(splitPane);
-        
+
         textView = new JTextArea();
         textView.setEditable(false);
         textView.setLineWrap(true);
         contentPane.add(textView);
     }
-    
+
     /**
      * Create a node given a Multipart body.
      * Add the Preamble, all Body parts and the Epilogue to the node.
-     * 
+     *
      * @param multipart the Multipart.
      * @return the root node of the tree.
      */
@@ -148,17 +150,17 @@ public class MessageTree extends JPanel 
 
         for (Field field : header.getFields()) {
             String name = field.getName();
-            
+
             node.add(new DefaultMutableTreeNode(new ObjectWrapper(name, field)));
-        }        
+        }
 
         return node;
     }
-    
+
     /**
      * Create a node given a Multipart body.
      * Add the Preamble, all Body parts and the Epilogue to the node.
-     * 
+     *
      * @param multipart the Multipart.
      * @return the root node of the tree.
      */
@@ -176,17 +178,17 @@ public class MessageTree extends JPanel 
 
         return node;
     }
-    
+
     /**
-     * Creates the tree nodes given a MIME entity (either a Message or 
+     * Creates the tree nodes given a MIME entity (either a Message or
      * a BodyPart).
-     * 
+     *
      * @param entity the entity.
-     * @return the root node of the tree displaying the specified entity and 
+     * @return the root node of the tree displaying the specified entity and
      *         its children.
      */
     private DefaultMutableTreeNode createNode(Entity entity) {
-        
+
         /*
          * Create the root node for the entity. It's either a
          * Message or a Body part.
@@ -202,22 +204,22 @@ public class MessageTree extends JPanel 
          * Add the node encapsulating the entity Header.
          */
         node.add(createNode(entity.getHeader()));
-        
+
         Body body = entity.getBody();
-        
+
         if (body instanceof Multipart) {
             /*
              * The body of the entity is a Multipart.
              */
-            
+
             node.add(createNode((Multipart) body));
         } else if (body instanceof MessageImpl) {
             /*
              * The body is another Message.
              */
-            
+
             node.add(createNode((MessageImpl) body));
-            
+
         } else {
             /*
              * Discrete Body (either of type TextBody or BinaryBody).
@@ -226,19 +228,19 @@ public class MessageTree extends JPanel 
             if (body instanceof BinaryBody) {
                 type = "Binary body";
             }
-            
+
             type += " (" + entity.getMimeType() + ")";
             node.add(new DefaultMutableTreeNode(new ObjectWrapper(type, body)));
-            
+
         }
-        
+
         return node;
     }
-    
+
     /**
      * Called whenever the selection changes in the JTree instance showing
      * the Message nodes.
-     * 
+     *
      * @param e the event.
      */
     public void valueChanged(TreeSelectionEvent e) {
@@ -246,15 +248,15 @@ public class MessageTree extends JPanel 
                 tree.getLastSelectedPathComponent();
 
         textView.setText("");
-        
+
         if (node == null) {
             return;
         }
-        
+
         Object o = ((ObjectWrapper) node.getUserObject()).getObject();
 
         if (node.isLeaf()) {
-            
+
             if (o instanceof TextBody){
                 /*
                  * A text body. Display its contents.
@@ -271,7 +273,7 @@ public class MessageTree extends JPanel 
                     ex.printStackTrace();
                 }
                 textView.setText(sb.toString());
-                
+
             } else if (o instanceof BinaryBody){
                 /*
                  * A binary body. Display its MIME type and length in bytes.
@@ -287,10 +289,10 @@ public class MessageTree extends JPanel 
                     ex.printStackTrace();
                 }
                 textView.setText("Binary body\n"
-                               + "MIME type: " 
-                                   + body.getParent().getMimeType() + "\n" 
+                               + "MIME type: "
+                                   + body.getParent().getMimeType() + "\n"
                                + "Size of decoded data: " + size + " bytes");
-                
+
             } else if (o instanceof ContentTypeField) {
                 /*
                  * Content-Type field.
@@ -303,7 +305,7 @@ public class MessageTree extends JPanel 
                     sb.append(name + " = " + params.get(name) + "\n");
                 }
                 textView.setText(sb.toString());
-                
+
             } else if (o instanceof AddressListField) {
                 /*
                  * An address field (From, To, Cc, etc)
@@ -316,31 +318,31 @@ public class MessageTree extends JPanel 
                     sb.append(AddressFormatter.format(mb, false) + "\n");
                 }
                 textView.setText(sb.toString());
-                
+
             } else if (o instanceof DateTimeField) {
                 Date date = ((DateTimeField) o).getDate();
-                textView.setText(date.toString());                
+                textView.setText(date.toString());
             } else if (o instanceof UnstructuredField){
-                textView.setText(((UnstructuredField) o).getValue());                
+                textView.setText(((UnstructuredField) o).getValue());
             } else if (o instanceof Field){
-                textView.setText(((Field) o).getBody());                
+                textView.setText(((Field) o).getBody());
             } else {
                 /*
-                 * The Object should be a Header or a String containing a 
+                 * The Object should be a Header or a String containing a
                  * Preamble or Epilogue.
                  */
-                textView.setText(o.toString());                
+                textView.setText(o.toString());
             }
-            
+
         }
     }
-    
+
     /**
      * Creates and displays the gui.
-     * 
+     *
      * @param message the Message to display in the tree.
      */
-    private static void createAndShowGUI(MessageImpl message) {
+    private static void createAndShowGUI(Message message) {
         /*
          * Create and set up the window.
          */
@@ -360,18 +362,18 @@ public class MessageTree extends JPanel 
         frame.pack();
         frame.setVisible(true);
     }
-    
+
     public static void main(String[] args) {
         try {
-            
-            final MessageImpl message = new MessageImpl(new FileInputStream(args[0]));
-            
+
+            final Message message = MimeBuilder.parse(new FileInputStream(args[0]));
+
             javax.swing.SwingUtilities.invokeLater(new Runnable() {
                 public void run() {
                     createAndShowGUI(message);
                 }
             });
-        
+
         } catch (ArrayIndexOutOfBoundsException e) {
             System.err.println("Wrong number of arguments.");
             System.err.println("Usage: org.mime4j.samples.tree.MessageTree"