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/19 19:50:35 UTC

svn commit: r1060898 [1/2] - in /james/mime4j/trunk: ./ 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/field/ dom/src/main/java/org/apache/james/mime4j/field/add...

Author: olegk
Date: Wed Jan 19 18:50:34 2011
New Revision: 1060898

URL: http://svn.apache.org/viewvc?rev=1060898&view=rev
Log:
Moved all implementation details from 'dom' to 'message'; 'dom' is mostly pure interfaces now (merged from refactoring branch)

Added:
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/address/AddressBuilder.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/field/address/AddressBuilder.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/address/AddressFormatter.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/field/address/AddressFormatter.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/address/BaseNode.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/field/address/BaseNode.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/address/Builder.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/field/address/Builder.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/AbstractEntity.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/AbstractEntity.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/AbstractHeader.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/AbstractHeader.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/AbstractMessage.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/AbstractMessage.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/AbstractMultipart.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/AbstractMultipart.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/main/java/org/apache/james/mime4j/message/MimeBuilder.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MimeBuilderCopyTest.java
      - copied unchanged from r1060896, james/mime4j/branches/dom-api-refactoring/dom/src/test/java/org/apache/james/mime4j/dom/MimeBuilderCopyTest.java
Removed:
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/address/formatter/
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/address/parser/
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyCopier.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/CopyConstructorTest.java
Modified:
    james/mime4j/trunk/   (props changed)
    james/mime4j/trunk/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Header.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Message.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Multipart.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/AddressListFieldImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/Fields.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxFieldImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxListFieldImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MaximalBodyDescriptor.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java
    james/mime4j/trunk/dom/src/main/jjtree/org/apache/james/mime4j/field/address/AddressListParser.jjt
    james/mime4j/trunk/dom/src/main/jjtree/org/apache/james/mime4j/field/address/ParseException.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/EntityTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/ExampleMessagesRoundtripTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/HeaderTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MessageCompleteMailTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MessageHeadlessParserTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MessageParserTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MessageTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MessageWriteToTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/dom/MultipartFormTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/field/FieldsTest.java
    james/mime4j/trunk/dom/src/test/java/org/apache/james/mime4j/field/address/AddressTest.java
    james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java
    james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/TextPlainMessage.java
    james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
    james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java

Propchange: james/mime4j/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan 19 18:50:34 2011
@@ -1 +1 @@
-/james/mime4j/branches/dom-api-refactoring:1058070-1058305
+/james/mime4j/branches/dom-api-refactoring:1058069-1060896

Modified: james/mime4j/trunk/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java (original)
+++ james/mime4j/trunk/benchmark/src/main/java/org/apache/james/mime4j/LongMultipartReadBench.java Wed Jan 19 18:50:34 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/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Entity.java Wed Jan 19 18:50:34 2011
@@ -19,41 +19,18 @@
 
 package org.apache.james.mime4j.dom;
 
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.james.mime4j.dom.field.ContentDispositionField;
-import org.apache.james.mime4j.dom.field.ContentTransferEncodingField;
-import org.apache.james.mime4j.dom.field.ContentTypeField;
-import org.apache.james.mime4j.dom.field.Field;
-import org.apache.james.mime4j.dom.field.FieldName;
-
 /**
  * MIME entity. An entity has a header and a body (see RFC 2045).
  */
-public abstract class Entity implements Disposable {
-    private Header header = null;
-    private Body body = null;
-    private Entity parent = null;
-
-    /**
-     * Creates a new <code>Entity</code>. Typically invoked implicitly by a
-     * subclass constructor.
-     */
-    protected Entity() {
-    }
-
+public interface Entity extends Disposable {
+    
     /**
      * Gets the parent entity of this entity.
      * Returns <code>null</code> if this is the root entity.
      * 
      * @return the parent or <code>null</code>.
      */
-    public Entity getParent() {
-        return parent;
-    }
+    Entity getParent();
     
     /**
      * Sets the parent entity of this entity.
@@ -61,36 +38,28 @@ public abstract class Entity implements 
      * @param parent the parent entity or <code>null</code> if
      *        this will be the root entity.
      */
-    public void setParent(Entity parent) {
-        this.parent = parent;
-    }
-    
+    void setParent(Entity parent);
+
     /**
      * Gets the entity header.
      * 
      * @return the header.
      */
-    public Header getHeader() {
-        return header;
-    }
+    Header getHeader();
     
     /**
      * Sets the entity header.
      * 
      * @param header the header.
      */
-    public void setHeader(Header header) {
-        this.header = header;
-    }
+    void setHeader(Header header);
     
     /**
      * Gets the body of this entity.
      * 
      * @return the body,
      */
-    public Body getBody() {
-        return body;
-    }
+    Body getBody();
 
     /**
      * Sets the body of this entity.
@@ -98,14 +67,8 @@ public abstract class Entity implements 
      * @param body the body.
      * @throws IllegalStateException if the body has already been set.
      */
-    public void setBody(Body body) {
-        if (this.body != null)
-            throw new IllegalStateException("body already set");
-
-        this.body = body;
-        body.setParent(this);
-    }
-
+    void setBody(Body body);
+    
     /**
      * Removes and returns the body of this entity. The removed body may be
      * attached to another entity. If it is no longer needed it should be
@@ -113,141 +76,18 @@ public abstract class Entity implements 
      * 
      * @return the removed body or <code>null</code> if no body was set.
      */
-    public Body removeBody() {
-        if (body == null)
-            return null;
-
-        Body body = this.body;
-        this.body = null;
-        body.setParent(null);
-
-        return body;
-    }
-
-    /**
-     * Sets the specified message as body of this entity and the content type to
-     * &quot;message/rfc822&quot;. A <code>Header</code> is created if this
-     * entity does not already have one.
-     * 
-     * @param message
-     *            the message to set as body.
-     */
-    public void setMessage(Message message) {
-        setBody(message, "message/rfc822", null);
-    }
-
-    /**
-     * Sets the specified multipart as body of this entity. Also sets the
-     * content type accordingly and creates a message boundary string. A
-     * <code>Header</code> is created if this entity does not already have
-     * one.
-     * 
-     * @param multipart
-     *            the multipart to set as body.
-     */
-    public void setMultipart(Multipart multipart) {
-        String mimeType = "multipart/" + multipart.getSubType();
-        Map<String, String> parameters = Collections.singletonMap("boundary",
-                newUniqueBoundary());
-
-        setBody(multipart, mimeType, parameters);
-    }
-
-    /**
-     * Sets the specified multipart as body of this entity. Also sets the
-     * content type accordingly and creates a message boundary string. A
-     * <code>Header</code> is created if this entity does not already have
-     * one.
-     * 
-     * @param multipart
-     *            the multipart to set as body.
-     * @param parameters
-     *            additional parameters for the Content-Type header field.
-     */
-    public void setMultipart(Multipart multipart, Map<String, String> parameters) {
-        String mimeType = "multipart/" + multipart.getSubType();
-        if (!parameters.containsKey("boundary")) {
-            parameters = new HashMap<String, String>(parameters);
-            parameters.put("boundary", newUniqueBoundary());
-        }
-
-        setBody(multipart, mimeType, parameters);
-    }
-
-    /**
-     * Sets the specified <code>TextBody</code> as body of this entity and the
-     * content type to &quot;text/plain&quot;. A <code>Header</code> is
-     * created if this entity does not already have one.
-     * 
-     * @param textBody
-     *            the <code>TextBody</code> to set as body.
-     * @see org.apache.james.mime4j.message.BodyFactory#textBody(String)
-     */
-    public void setText(TextBody textBody) {
-        setText(textBody, "plain");
-    }
-
+    Body removeBody();
+    
     /**
-     * Sets the specified <code>TextBody</code> as body of this entity. Also
-     * sets the content type according to the specified sub-type. A
-     * <code>Header</code> is created if this entity does not already have
-     * one.
-     * 
-     * @param textBody
-     *            the <code>TextBody</code> to set as body.
-     * @param subtype
-     *            the text subtype (e.g. &quot;plain&quot;, &quot;html&quot; or
-     *            &quot;xml&quot;).
-     * @see org.apache.james.mime4j.message.BodyFactory#textBody(String)
+     * 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.
      */
-    public void setText(TextBody textBody, String subtype) {
-        String mimeType = "text/" + subtype;
-
-        Map<String, String> parameters = null;
-        String mimeCharset = textBody.getMimeCharset();
-        if (mimeCharset != null && !mimeCharset.equalsIgnoreCase("us-ascii")) {
-            parameters = Collections.singletonMap("charset", mimeCharset);
-        }
-
-        setBody(textBody, mimeType, parameters);
-    }
-
-    /**
-     * Sets the body of this entity and sets the content-type to the specified
-     * value. A <code>Header</code> is created if this entity does not already
-     * have one.
-     * 
-     * @param body
-     *            the body.
-     * @param mimeType
-     *            the MIME media type of the specified body
-     *            (&quot;type/subtype&quot;).
-     */
-    public void setBody(Body body, String mimeType) {
-        setBody(body, mimeType, null);
-    }
-
-    /**
-     * Sets the body of this entity and sets the content-type to the specified
-     * value. A <code>Header</code> is created if this entity does not already
-     * have one.
-     * 
-     * @param body
-     *            the body.
-     * @param mimeType
-     *            the MIME media type of the specified body
-     *            (&quot;type/subtype&quot;).
-     * @param parameters
-     *            additional parameters for the Content-Type header field.
-     */
-    public void setBody(Body body, String mimeType,
-            Map<String, String> parameters) {
-        setBody(body);
-
-        Header header = obtainHeader();
-        header.setField(newContentType(mimeType, parameters));
-    }
-
+    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
@@ -255,296 +95,20 @@ public abstract class Entity implements 
      * 
      * @return the MIME type.
      */
-    public String getMimeType() {
-        ContentTypeField child = 
-            getContentTypeField();
-        ContentTypeField parent = getParent() != null 
-            ? (ContentTypeField) getParent().getHeader().
-                                                getField(FieldName.CONTENT_TYPE)
-            : null;
-        
-        return calcMimeType(child, parent);
-    }
+    String getMimeType();
 
-    private ContentTypeField getContentTypeField() {
-        return (ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE);
-    }
-    
     /**
      * Determines the MIME character set encoding of this <code>Entity</code>.
      * 
      * @return the MIME character set encoding.
      */
-    public String getCharset() {
-        return calcCharset((ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE));
-    }
+    String getCharset();
     
     /**
      * Determines the transfer encoding of this <code>Entity</code>.
      * 
      * @return the transfer encoding.
      */
-    public String getContentTransferEncoding() {
-        ContentTransferEncodingField f = (ContentTransferEncodingField) 
-                        getHeader().getField(FieldName.CONTENT_TRANSFER_ENCODING);
-        
-        return calcTransferEncoding(f);
-    }
-
-    /**
-     * Sets the transfer encoding of this <code>Entity</code> to the specified
-     * value.
-     * 
-     * @param contentTransferEncoding
-     *            transfer encoding to use.
-     */
-    public void setContentTransferEncoding(String contentTransferEncoding) {
-        Header header = obtainHeader();
-        header.setField(newContentTransferEncoding(contentTransferEncoding));
-    }
-
-    /**
-     * Return the disposition type of the content disposition of this
-     * <code>Entity</code>.
-     * 
-     * @return the disposition type or <code>null</code> if no disposition
-     *         type has been set.
-     */
-    public String getDispositionType() {
-        ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
-        if (field == null)
-            return null;
-
-        return field.getDispositionType();
-    }
-
-    /**
-     * Sets the content disposition of this <code>Entity</code> to the
-     * specified disposition type. No filename, size or date parameters
-     * are included in the content disposition.
-     * 
-     * @param dispositionType
-     *            disposition type value (usually <code>inline</code> or
-     *            <code>attachment</code>).
-     */
-    public void setContentDisposition(String dispositionType) {
-        Header header = obtainHeader();
-        header.setField(newContentDisposition(dispositionType, null, -1, null,
-                null, null));
-    }
-
-    /**
-     * Sets the content disposition of this <code>Entity</code> to the
-     * specified disposition type and filename. No size or date parameters are
-     * included in the content disposition.
-     * 
-     * @param dispositionType
-     *            disposition type value (usually <code>inline</code> or
-     *            <code>attachment</code>).
-     * @param filename
-     *            filename parameter value or <code>null</code> if the
-     *            parameter should not be included.
-     */
-    public void setContentDisposition(String dispositionType, String filename) {
-        Header header = obtainHeader();
-        header.setField(newContentDisposition(dispositionType, filename, -1,
-                null, null, null));
-    }
-
-    /**
-     * Sets the content disposition of this <code>Entity</code> to the
-     * specified values. No date parameters are included in the content
-     * disposition.
-     * 
-     * @param dispositionType
-     *            disposition type value (usually <code>inline</code> or
-     *            <code>attachment</code>).
-     * @param filename
-     *            filename parameter value or <code>null</code> if the
-     *            parameter should not be included.
-     * @param size
-     *            size parameter value or <code>-1</code> if the parameter
-     *            should not be included.
-     */
-    public void setContentDisposition(String dispositionType, String filename,
-            long size) {
-        Header header = obtainHeader();
-        header.setField(newContentDisposition(dispositionType, filename, size,
-                null, null, null));
-    }
-
-    /**
-     * Sets the content disposition of this <code>Entity</code> to the
-     * specified values.
-     * 
-     * @param dispositionType
-     *            disposition type value (usually <code>inline</code> or
-     *            <code>attachment</code>).
-     * @param filename
-     *            filename parameter value or <code>null</code> if the
-     *            parameter should not be included.
-     * @param size
-     *            size parameter value or <code>-1</code> if the parameter
-     *            should not be included.
-     * @param creationDate
-     *            creation-date parameter value or <code>null</code> if the
-     *            parameter should not be included.
-     * @param modificationDate
-     *            modification-date parameter value or <code>null</code> if
-     *            the parameter should not be included.
-     * @param readDate
-     *            read-date parameter value or <code>null</code> if the
-     *            parameter should not be included.
-     */
-    public void setContentDisposition(String dispositionType, String filename,
-            long size, Date creationDate, Date modificationDate, Date readDate) {
-        Header header = obtainHeader();
-        header.setField(newContentDisposition(dispositionType, filename, size,
-                creationDate, modificationDate, readDate));
-    }
-
-    /**
-     * Returns the filename parameter of the content disposition of this
-     * <code>Entity</code>.
-     * 
-     * @return the filename parameter of the content disposition or
-     *         <code>null</code> if the filename has not been set.
-     */
-    public String getFilename() {
-        ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
-        if (field == null)
-            return null;
-
-        return field.getFilename();
-    }
-    
-    /**
-     * Sets the filename parameter of the content disposition of this
-     * <code>Entity</code> to the specified value. If this entity does not
-     * have a content disposition header field a new one with disposition type
-     * <code>attachment</code> is created.
-     * 
-     * @param filename
-     *            filename parameter value or <code>null</code> if the
-     *            parameter should be removed.
-     */
-    public void setFilename(String filename) {
-        Header header = obtainHeader();
-        ContentDispositionField field = (ContentDispositionField) header
-                .getField(FieldName.CONTENT_DISPOSITION);
-        if (field == null) {
-            if (filename != null) {
-                header.setField(newContentDisposition(
-                        ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT,
-                        filename, -1, null, null, null));
-            }
-        } else {
-            String dispositionType = field.getDispositionType();
-            Map<String, String> parameters = new HashMap<String, String>(field
-                    .getParameters());
-            if (filename == null) {
-                parameters.remove(ContentDispositionField.PARAM_FILENAME);
-            } else {
-                parameters
-                        .put(ContentDispositionField.PARAM_FILENAME, filename);
-            }
-            header.setField(newContentDisposition(dispositionType, parameters));
-        }
-    }
-
-    /**
-     * Determines if the MIME type of this <code>Entity</code> matches the
-     * given one. MIME types are case-insensitive.
-     * 
-     * @param type the MIME type to match against.
-     * @return <code>true</code> on match, <code>false</code> otherwise.
-     */
-    public boolean isMimeType(String type) {
-        return getMimeType().equalsIgnoreCase(type);
-    }
-    
-    /**
-     * 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.
-     */
-    public boolean isMultipart() {
-        ContentTypeField f = getContentTypeField();
-        return f != null
-                && f.getBoundary() != null
-                && getMimeType().startsWith(
-                        ContentTypeField.TYPE_MULTIPART_PREFIX);
-    }
-
-    /**
-     * Disposes of the body of this entity. Note that the dispose call does not
-     * get forwarded to the parent entity of this Entity.
-     * 
-     * Subclasses that need to free resources should override this method and
-     * invoke super.dispose().
-     * 
-     * @see org.apache.james.mime4j.dom.Disposable#dispose()
-     */
-    public void dispose() {
-        if (body != null) {
-            body.dispose();
-        }
-    }
-
-    /**
-     * Obtains the header of this entity. Creates and sets a new header if this
-     * entity's header is currently <code>null</code>.
-     * 
-     * @return the header of this entity; never <code>null</code>.
-     */
-    Header obtainHeader() {
-        if (header == null) {
-            header = new Header();
-        }
-        return header;
-    }
-
-    /**
-     * Obtains the header field with the specified name.
-     * 
-     * @param <F>
-     *            concrete field type.
-     * @param fieldName
-     *            name of the field to retrieve.
-     * @return the header field or <code>null</code> if this entity has no
-     *         header or the header contains no such field.
-     */
-    <F extends Field> F obtainField(String fieldName) {
-        Header header = getHeader();
-        if (header == null)
-            return null;
-
-        @SuppressWarnings("unchecked")
-        F field = (F) header.getField(fieldName);
-        return field;
-    }
-
-    protected abstract String newUniqueBoundary();
-
-    protected abstract ContentDispositionField newContentDisposition(
-            String dispositionType, String filename, long size,
-            Date creationDate, Date modificationDate, Date readDate);
-
-    protected abstract ContentDispositionField newContentDisposition(
-            String dispositionType, Map<String, String> parameters);
-
-    protected abstract ContentTypeField newContentType(String mimeType,
-            Map<String, String> parameters);
-
-    protected abstract ContentTransferEncodingField newContentTransferEncoding(
-            String contentTransferEncoding);
-
-    protected abstract String calcMimeType(ContentTypeField child, ContentTypeField parent);
-
-    protected abstract String calcTransferEncoding(ContentTransferEncodingField f);
+    String getContentTransferEncoding();
 
-    protected abstract String calcCharset(ContentTypeField contentType);
-}
+}
\ No newline at end of file

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Header.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Header.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Header.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Header.java Wed Jan 19 18:50:34 2011
@@ -19,59 +19,22 @@
 
 package org.apache.james.mime4j.dom;
 
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.james.mime4j.dom.field.Field;
 
 /**
  * The header of an entity (see RFC 2045).
  */
-public class Header implements Iterable<Field> {
-
-    private List<Field> fields = new LinkedList<Field>();
-    private Map<String, List<Field>> fieldMap = new HashMap<String, List<Field>>();
-    
-    /**
-     * Creates a new empty <code>Header</code>.
-     */
-    public Header() {
-    }
-
-    /**
-     * 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 Header(Header other) {
-        for (Field otherField : other.fields) {
-            addField(otherField);
-        }
-    }
+public interface Header extends Iterable<Field> {
 
     /**
      * Adds a field to the end of the list of fields.
      * 
      * @param field the field to add.
      */
-    public void addField(Field field) {
-        List<Field> values = fieldMap.get(field.getName().toLowerCase());
-        if (values == null) {
-            values = new LinkedList<Field>();
-            fieldMap.put(field.getName().toLowerCase(), values);
-        }
-        values.add(field);
-        fields.add(field);
-    }
+    void addField(Field field);
     
     /**
      * Gets the fields of this header. The returned list will not be
@@ -79,9 +42,7 @@ public class Header implements Iterable<
      * 
      * @return the list of <code>Field</code> objects.
      */
-    public List<Field> getFields() {
-        return Collections.unmodifiableList(fields);
-    }
+    List<Field> getFields();
 
     /**
      * Gets a <code>Field</code> given a field name. If there are multiple
@@ -90,13 +51,7 @@ public class Header implements Iterable<
      * @param name the field name (e.g. From, Subject).
      * @return the field or <code>null</code> if none found.
      */
-    public Field getField(String name) {
-        List<Field> l = fieldMap.get(name.toLowerCase());
-        if (l != null && !l.isEmpty()) {
-            return l.get(0);
-        }
-        return null;
-    }
+    Field getField(String name);
     
     /**
      * Gets all <code>Field</code>s having the specified field name. 
@@ -104,26 +59,14 @@ public class Header implements Iterable<
      * @param name the field name (e.g. From, Subject).
      * @return the list of fields.
      */
-    public List<Field> getFields(final String name) {
-        final String lowerCaseName = name.toLowerCase();
-        final List<Field> l = fieldMap.get(lowerCaseName);
-        final List<Field> results;
-        if (l == null || l.isEmpty()) {
-            results = Collections.emptyList();
-        } else {
-            results = Collections.unmodifiableList(l);
-        }
-        return results;
-    }
+    List<Field> getFields(final String name);
 
     /**
      * Returns an iterator over the list of fields of this header.
      * 
      * @return an iterator.
      */
-    public Iterator<Field> iterator() {
-        return Collections.unmodifiableList(fields).iterator();
-    }
+    Iterator<Field> iterator();
 
     /**
      * Removes all <code>Field</code>s having the specified field name.
@@ -132,20 +75,7 @@ public class Header implements Iterable<
      *            the field name (e.g. From, Subject).
      * @return number of fields removed.
      */
-    public int removeFields(String name) {
-        final String lowerCaseName = name.toLowerCase();
-        List<Field> removed = fieldMap.remove(lowerCaseName);
-        if (removed == null || removed.isEmpty())
-            return 0;
-
-        for (Iterator<Field> iterator = fields.iterator(); iterator.hasNext();) {
-            Field field = iterator.next();
-            if (field.getName().equalsIgnoreCase(name))
-                iterator.remove();
-        }
-
-        return removed.size();
-    }
+    int removeFields(String name);
 
     /**
      * Sets or replaces a field. This method is useful for header fields such as
@@ -159,46 +89,6 @@ public class Header implements Iterable<
      * 
      * @param field the field to set.
      */
-    public void setField(Field field) {
-        final String lowerCaseName = field.getName().toLowerCase();
-        List<Field> l = fieldMap.get(lowerCaseName);
-        if (l == null || l.isEmpty()) {
-            addField(field);
-            return;
-        }
-
-        l.clear();
-        l.add(field);
-
-        int firstOccurrence = -1;
-        int index = 0;
-        for (Iterator<Field> iterator = fields.iterator(); iterator.hasNext(); index++) {
-            Field f = iterator.next();
-            if (f.getName().equalsIgnoreCase(field.getName())) {
-                iterator.remove();
-
-                if (firstOccurrence == -1)
-                    firstOccurrence = index;
-            }
-        }
-
-        fields.add(firstOccurrence, field);
-    }
-
-    /**
-     * Return Header Object as String representation. Each headerline is
-     * seperated by "\r\n"
-     * 
-     * @return headers
-     */
-    @Override
-    public String toString() {
-        StringBuilder str = new StringBuilder(128);
-        for (Field field : fields) {
-            str.append(field.toString());
-            str.append("\r\n");
-        }
-        return str.toString();
-    }
-
+    void setField(Field field);
+    
 }

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Message.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Message.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Message.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Message.java Wed Jan 19 18:50:34 2011
@@ -21,9 +21,7 @@ package org.apache.james.mime4j.dom;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
 import java.util.TimeZone;
 
@@ -31,27 +29,18 @@ import org.apache.james.mime4j.dom.addre
 import org.apache.james.mime4j.dom.address.AddressList;
 import org.apache.james.mime4j.dom.address.Mailbox;
 import org.apache.james.mime4j.dom.address.MailboxList;
-import org.apache.james.mime4j.dom.field.AddressListField;
-import org.apache.james.mime4j.dom.field.DateTimeField;
-import org.apache.james.mime4j.dom.field.Field;
-import org.apache.james.mime4j.dom.field.FieldName;
-import org.apache.james.mime4j.dom.field.MailboxField;
-import org.apache.james.mime4j.dom.field.MailboxListField;
-import org.apache.james.mime4j.dom.field.UnstructuredField;
 
-public abstract class Message extends Entity implements Body {
+public interface Message extends Entity, Body {
 
     /**
-     * Write the content to the given output stream using the
-     * {@link org.apache.james.mime4j.message.MessageWriter#DEFAULT default} message writer.
+     * Write the content to the given output stream.
      * 
      * @param out
      *            the output stream to write to.
      * @throws IOException
      *             in case of an I/O error
-     * @see org.apache.james.mime4j.message.MessageWriter
      */
-    public abstract void writeTo(OutputStream out) throws IOException;
+    void writeTo(OutputStream out) throws IOException;
 
     /**
      * Returns the value of the <i>Message-ID</i> header field of this message
@@ -59,13 +48,7 @@ public abstract class Message extends En
      * 
      * @return the identifier of this message.
      */
-    public String getMessageId() {
-        Field field = obtainField(FieldName.MESSAGE_ID);
-        if (field == null)
-            return null;
-
-        return field.getBody();
-    }
+    String getMessageId();
 
     /**
      * Creates and sets a new <i>Message-ID</i> header field for this message.
@@ -76,13 +59,7 @@ public abstract class Message extends En
      *            host name to be included in the identifier or
      *            <code>null</code> if no host name should be included.
      */
-    public void createMessageId(String hostname) {
-        Header header = obtainHeader();
-
-        header.setField(newMessageId(hostname));
-    }
-
-    protected abstract Field newMessageId(String hostname);
+    void createMessageId(String hostname);
 
     /**
      * Returns the (decoded) value of the <i>Subject</i> header field of this
@@ -90,13 +67,7 @@ public abstract class Message extends En
      * 
      * @return the subject of this message.
      */
-    public String getSubject() {
-        UnstructuredField field = obtainField(FieldName.SUBJECT);
-        if (field == null)
-            return null;
-
-        return field.getValue();
-    }
+    String getSubject();
 
     /**
      * Sets the <i>Subject</i> header field for this message. The specified
@@ -108,15 +79,7 @@ public abstract class Message extends En
      *            subject to set or <code>null</code> to remove the subject
      *            header field.
      */
-    public void setSubject(String subject) {
-        Header header = obtainHeader();
-
-        if (subject == null) {
-            header.removeFields(FieldName.SUBJECT);
-        } else {
-            header.setField(newSubject(subject));
-        }
-    }
+    void setSubject(String subject);
 
     /**
      * Returns the value of the <i>Date</i> header field of this message as
@@ -124,13 +87,7 @@ public abstract class Message extends En
      * 
      * @return the date of this message.
      */
-    public Date getDate() {
-        DateTimeField dateField = obtainField(FieldName.DATE);
-        if (dateField == null)
-            return null;
-
-        return dateField.getDate();
-    }
+    Date getDate();
 
     /**
      * Sets the <i>Date</i> header field for this message. This method uses the
@@ -141,9 +98,7 @@ public abstract class Message extends En
      *            date to set or <code>null</code> to remove the date header
      *            field.
      */
-    public void setDate(Date date) {
-        setDate(date, null);
-    }
+    void setDate(Date date);
 
     /**
      * Sets the <i>Date</i> header field for this message. The specified
@@ -156,15 +111,7 @@ public abstract class Message extends En
      * @param zone
      *            a time zone.
      */
-    public void setDate(Date date, TimeZone zone) {
-        Header header = obtainHeader();
-
-        if (date == null) {
-            header.removeFields(FieldName.DATE);
-        } else {
-            header.setField(newDate(date, zone));
-        }
-    }
+    void setDate(Date date, TimeZone zone);
 
     /**
      * Returns the value of the <i>Sender</i> header field of this message as
@@ -173,9 +120,7 @@ public abstract class Message extends En
      * 
      * @return the sender of this message.
      */
-    public Mailbox getSender() {
-        return getMailbox(FieldName.SENDER);
-    }
+    Mailbox getSender();
 
     /**
      * Sets the <i>Sender</i> header field of this message to the specified
@@ -185,9 +130,7 @@ public abstract class Message extends En
      *            address to set or <code>null</code> to remove the header
      *            field.
      */
-    public void setSender(Mailbox sender) {
-        setMailbox(FieldName.SENDER, sender);
-    }
+    void setSender(Mailbox sender);
 
     /**
      * Returns the value of the <i>From</i> header field of this message as
@@ -196,9 +139,7 @@ public abstract class Message extends En
      * 
      * @return value of the from field of this message.
      */
-    public MailboxList getFrom() {
-        return getMailboxList(FieldName.FROM);
-    }
+    MailboxList getFrom();
 
     /**
      * Sets the <i>From</i> header field of this message to the specified
@@ -208,9 +149,7 @@ public abstract class Message extends En
      *            address to set or <code>null</code> to remove the header
      *            field.
      */
-    public void setFrom(Mailbox from) {
-        setMailboxList(FieldName.FROM, from);
-    }
+    void setFrom(Mailbox from);
 
     /**
      * Sets the <i>From</i> header field of this message to the specified
@@ -220,9 +159,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or no arguments to
      *            remove the header field.
      */
-    public void setFrom(Mailbox... from) {
-        setMailboxList(FieldName.FROM, from);
-    }
+    void setFrom(Mailbox... from);
 
     /**
      * Sets the <i>From</i> header field of this message to the specified
@@ -232,9 +169,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or an empty collection
      *            to remove the header field.
      */
-    public void setFrom(Collection<Mailbox> from) {
-        setMailboxList(FieldName.FROM, from);
-    }
+    void setFrom(Collection<Mailbox> from);
 
     /**
      * Returns the value of the <i>To</i> header field of this message as
@@ -243,9 +178,7 @@ public abstract class Message extends En
      * 
      * @return value of the to field of this message.
      */
-    public AddressList getTo() {
-        return getAddressList(FieldName.TO);
-    }
+    AddressList getTo();
 
     /**
      * Sets the <i>To</i> header field of this message to the specified
@@ -255,9 +188,7 @@ public abstract class Message extends En
      *            address to set or <code>null</code> to remove the header
      *            field.
      */
-    public void setTo(Address to) {
-        setAddressList(FieldName.TO, to);
-    }
+    void setTo(Address to);
 
     /**
      * Sets the <i>To</i> header field of this message to the specified
@@ -267,9 +198,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or no arguments to
      *            remove the header field.
      */
-    public void setTo(Address... to) {
-        setAddressList(FieldName.TO, to);
-    }
+    void setTo(Address... to);
 
     /**
      * Sets the <i>To</i> header field of this message to the specified
@@ -279,9 +208,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or an empty collection
      *            to remove the header field.
      */
-    public void setTo(Collection<Address> to) {
-        setAddressList(FieldName.TO, to);
-    }
+    void setTo(Collection<Address> to);
 
     /**
      * Returns the value of the <i>Cc</i> header field of this message as
@@ -290,9 +217,7 @@ public abstract class Message extends En
      * 
      * @return value of the cc field of this message.
      */
-    public AddressList getCc() {
-        return getAddressList(FieldName.CC);
-    }
+    AddressList getCc();
 
     /**
      * Sets the <i>Cc</i> header field of this message to the specified
@@ -302,9 +227,7 @@ public abstract class Message extends En
      *            address to set or <code>null</code> to remove the header
      *            field.
      */
-    public void setCc(Address cc) {
-        setAddressList(FieldName.CC, cc);
-    }
+    void setCc(Address cc);
 
     /**
      * Sets the <i>Cc</i> header field of this message to the specified
@@ -314,9 +237,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or no arguments to
      *            remove the header field.
      */
-    public void setCc(Address... cc) {
-        setAddressList(FieldName.CC, cc);
-    }
+    void setCc(Address... cc);
 
     /**
      * Sets the <i>Cc</i> header field of this message to the specified
@@ -326,9 +247,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or an empty collection
      *            to remove the header field.
      */
-    public void setCc(Collection<Address> cc) {
-        setAddressList(FieldName.CC, cc);
-    }
+    void setCc(Collection<Address> cc);
 
     /**
      * Returns the value of the <i>Bcc</i> header field of this message as
@@ -337,9 +256,7 @@ public abstract class Message extends En
      * 
      * @return value of the bcc field of this message.
      */
-    public AddressList getBcc() {
-        return getAddressList(FieldName.BCC);
-    }
+    AddressList getBcc();
 
     /**
      * Sets the <i>Bcc</i> header field of this message to the specified
@@ -349,9 +266,7 @@ public abstract class Message extends En
      *            address to set or <code>null</code> to remove the header
      *            field.
      */
-    public void setBcc(Address bcc) {
-        setAddressList(FieldName.BCC, bcc);
-    }
+    void setBcc(Address bcc);
 
     /**
      * Sets the <i>Bcc</i> header field of this message to the specified
@@ -361,9 +276,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or no arguments to
      *            remove the header field.
      */
-    public void setBcc(Address... bcc) {
-        setAddressList(FieldName.BCC, bcc);
-    }
+    void setBcc(Address... bcc);
 
     /**
      * Sets the <i>Bcc</i> header field of this message to the specified
@@ -373,9 +286,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or an empty collection
      *            to remove the header field.
      */
-    public void setBcc(Collection<Address> bcc) {
-        setAddressList(FieldName.BCC, bcc);
-    }
+    void setBcc(Collection<Address> bcc);
 
     /**
      * Returns the value of the <i>Reply-To</i> header field of this message as
@@ -384,9 +295,7 @@ public abstract class Message extends En
      * 
      * @return value of the reply to field of this message.
      */
-    public AddressList getReplyTo() {
-        return getAddressList(FieldName.REPLY_TO);
-    }
+    AddressList getReplyTo();
 
     /**
      * Sets the <i>Reply-To</i> header field of this message to the specified
@@ -396,9 +305,7 @@ public abstract class Message extends En
      *            address to set or <code>null</code> to remove the header
      *            field.
      */
-    public void setReplyTo(Address replyTo) {
-        setAddressList(FieldName.REPLY_TO, replyTo);
-    }
+    void setReplyTo(Address replyTo);
 
     /**
      * Sets the <i>Reply-To</i> header field of this message to the specified
@@ -408,9 +315,7 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or no arguments to
      *            remove the header field.
      */
-    public void setReplyTo(Address... replyTo) {
-        setAddressList(FieldName.REPLY_TO, replyTo);
-    }
+    void setReplyTo(Address... replyTo);
 
     /**
      * Sets the <i>Reply-To</i> header field of this message to the specified
@@ -420,93 +325,6 @@ public abstract class Message extends En
      *            addresses to set or <code>null</code> or an empty collection
      *            to remove the header field.
      */
-    public void setReplyTo(Collection<Address> replyTo) {
-        setAddressList(FieldName.REPLY_TO, replyTo);
-    }
-
-    private Mailbox getMailbox(String fieldName) {
-        MailboxField field = obtainField(fieldName);
-        if (field == null)
-            return null;
-
-        return field.getMailbox();
-    }
-
-    private void setMailbox(String fieldName, Mailbox mailbox) {
-        Header header = obtainHeader();
-
-        if (mailbox == null) {
-            header.removeFields(fieldName);
-        } else {
-            header.setField(newMailbox(fieldName, mailbox));
-        }
-    }
-
-    private MailboxList getMailboxList(String fieldName) {
-        MailboxListField field = obtainField(fieldName);
-        if (field == null)
-            return null;
-
-        return field.getMailboxList();
-    }
-
-    private void setMailboxList(String fieldName, Mailbox mailbox) {
-        setMailboxList(fieldName, mailbox == null ? null : Collections
-                .singleton(mailbox));
-    }
-
-    private void setMailboxList(String fieldName, Mailbox... mailboxes) {
-        setMailboxList(fieldName, mailboxes == null ? null : Arrays
-                .asList(mailboxes));
-    }
-
-    private void setMailboxList(String fieldName, Collection<Mailbox> mailboxes) {
-        Header header = obtainHeader();
-
-        if (mailboxes == null || mailboxes.isEmpty()) {
-            header.removeFields(fieldName);
-        } else {
-            header.setField(newMailboxList(fieldName, mailboxes));
-        }
-    }
-
-    private AddressList getAddressList(String fieldName) {
-        AddressListField field = obtainField(fieldName);
-        if (field == null)
-            return null;
-
-        return field.getAddressList();
-    }
-
-    private void setAddressList(String fieldName, Address address) {
-        setAddressList(fieldName, address == null ? null : Collections
-                .singleton(address));
-    }
-
-    private void setAddressList(String fieldName, Address... addresses) {
-        setAddressList(fieldName, addresses == null ? null : Arrays
-                .asList(addresses));
-    }
-
-    private void setAddressList(String fieldName, Collection<Address> addresses) {
-        Header header = obtainHeader();
-
-        if (addresses == null || addresses.isEmpty()) {
-            header.removeFields(fieldName);
-        } else {
-            header.setField(newAddressList(fieldName, addresses));
-        }
-    }
-
-    protected abstract AddressListField newAddressList(String fieldName, Collection<Address> addresses);
-
-    protected abstract UnstructuredField newSubject(String subject);
-
-    protected abstract DateTimeField newDate(Date date, TimeZone zone);
-
-    protected abstract MailboxField newMailbox(String fieldName, Mailbox mailbox);
-
-    protected abstract MailboxListField newMailboxList(String fieldName, Collection<Mailbox> mailboxes);
+    void setReplyTo(Collection<Address> replyTo);
 
-    
 }
\ No newline at end of file

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Multipart.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Multipart.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Multipart.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/dom/Multipart.java Wed Jan 19 18:50:34 2011
@@ -19,8 +19,6 @@
 
 package org.apache.james.mime4j.dom;
 
-import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -30,19 +28,7 @@ import java.util.List;
  * first body part while the epilogue consists of whatever characters come after
  * the last body part.
  */
-public abstract class Multipart implements Body {
-
-    protected List<Entity> bodyParts = new LinkedList<Entity>();
-    private Entity parent = null;
-
-    private String subType;
-
-    /**
-     * Creates a new empty <code>Multipart</code> instance.
-     */
-    public Multipart(String subType) {
-        this.subType = subType;
-    }
+public interface Multipart extends Body {
 
     /**
      * Gets the multipart sub-type. E.g. <code>alternative</code> (the
@@ -51,56 +37,21 @@ public abstract class Multipart implemen
      * 
      * @return the multipart sub-type.
      */
-    public String getSubType() {
-        return subType;
-    }
-
-    /**
-     * Sets the multipart sub-type. E.g. <code>alternative</code> or
-     * <code>parallel</code>. See RFC 2045 for common sub-types and their
-     * meaning.
-     * 
-     * @param subType
-     *            the sub-type.
-     */
-    public void setSubType(String subType) {
-        this.subType = subType;
-    }
-
-    /**
-     * @see org.apache.james.mime4j.dom.Body#getParent()
-     */
-    public Entity getParent() {
-        return parent;
-    }
-
-    /**
-     * @see org.apache.james.mime4j.dom.Body#setParent(org.apache.james.mime4j.dom.Entity)
-     */
-    public void setParent(Entity parent) {
-        this.parent = parent;
-        for (Entity bodyPart : bodyParts) {
-            bodyPart.setParent(parent);
-        }
-    }
-
+    String getSubType();
+    
     /**
      * Returns the number of body parts.
      * 
      * @return number of <code>Entity</code> objects.
      */
-    public int getCount() {
-        return bodyParts.size();
-    }
+    int getCount();
 
     /**
      * Gets the list of body parts. The list is immutable.
      * 
      * @return the list of <code>Entity</code> objects.
      */
-    public List<Entity> getBodyParts() {
-        return Collections.unmodifiableList(bodyParts);
-    }
+    public List<Entity> getBodyParts();
 
     /**
      * Sets the list of body parts.
@@ -108,12 +59,7 @@ public abstract class Multipart implemen
      * @param bodyParts
      *            the new list of <code>Entity</code> objects.
      */
-    public void setBodyParts(List<Entity> bodyParts) {
-        this.bodyParts = bodyParts;
-        for (Entity bodyPart : bodyParts) {
-            bodyPart.setParent(parent);
-        }
-    }
+    void setBodyParts(List<Entity> bodyParts);
 
     /**
      * Adds a body part to the end of the list of body parts.
@@ -121,13 +67,7 @@ public abstract class Multipart implemen
      * @param bodyPart
      *            the body part.
      */
-    public void addBodyPart(Entity bodyPart) {
-        if (bodyPart == null)
-            throw new IllegalArgumentException();
-
-        bodyParts.add(bodyPart);
-        bodyPart.setParent(parent);
-    }
+    void addBodyPart(Entity bodyPart);
 
     /**
      * Inserts a body part at the specified position in the list of body parts.
@@ -140,13 +80,7 @@ public abstract class Multipart implemen
      *             if the index is out of range (index &lt; 0 || index &gt;
      *             getCount()).
      */
-    public void addBodyPart(Entity bodyPart, int index) {
-        if (bodyPart == null)
-            throw new IllegalArgumentException();
-
-        bodyParts.add(index, bodyPart);
-        bodyPart.setParent(parent);
-    }
+    void addBodyPart(Entity bodyPart, int index);
 
     /**
      * Removes the body part at the specified position in the list of body
@@ -159,11 +93,7 @@ public abstract class Multipart implemen
      *             if the index is out of range (index &lt; 0 || index &gt;=
      *             getCount()).
      */
-    public Entity removeBodyPart(int index) {
-        Entity bodyPart = bodyParts.remove(index);
-        bodyPart.setParent(null);
-        return bodyPart;
-    }
+    Entity removeBodyPart(int index);
 
     /**
      * Replaces the body part at the specified position in the list of body
@@ -178,27 +108,14 @@ public abstract class Multipart implemen
      *             if the index is out of range (index &lt; 0 || index &gt;=
      *             getCount()).
      */
-    public Entity replaceBodyPart(Entity bodyPart, int index) {
-        if (bodyPart == null)
-            throw new IllegalArgumentException();
-
-        Entity replacedEntity = bodyParts.set(index, bodyPart);
-        if (bodyPart == replacedEntity)
-            throw new IllegalArgumentException(
-                    "Cannot replace body part with itself");
-
-        bodyPart.setParent(parent);
-        replacedEntity.setParent(null);
-
-        return replacedEntity;
-    }
+    Entity replaceBodyPart(Entity bodyPart, int index);
 
     /**
      * Gets the preamble or null if the message has no preamble.
      * 
      * @return the preamble.
      */
-    public abstract String getPreamble();
+    String getPreamble();
 
     /**
      * Sets the preamble with a value or null to remove the preamble.
@@ -206,14 +123,14 @@ public abstract class Multipart implemen
      * @param preamble
      *            the preamble.
      */
-    public abstract void setPreamble(String preamble);
-
+    void setPreamble(String preamble);
+    
     /**
      * Gets the epilogue or null if the message has no epilogue
      * 
      * @return the epilogue.
      */
-    public abstract String getEpilogue();
+    String getEpilogue();
 
     /**
      * Sets the epilogue value, or remove it if the value passed is null.
@@ -221,18 +138,6 @@ public abstract class Multipart implemen
      * @param epilogue
      *            the epilogue.
      */
-    public abstract void setEpilogue(String epilogue);
-
-    /**
-     * Disposes of the BodyParts of this Multipart. Note that the dispose call
-     * does not get forwarded to the parent entity of this Multipart.
-     * 
-     * @see org.apache.james.mime4j.dom.Disposable#dispose()
-     */
-    public void dispose() {
-        for (Entity bodyPart : bodyParts) {
-            bodyPart.dispose();
-        }
-    }
-
+    void setEpilogue(String epilogue);
+    
 }

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/AddressListFieldImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/AddressListFieldImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/AddressListFieldImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/AddressListFieldImpl.java Wed Jan 19 18:50:34 2011
@@ -21,8 +21,8 @@ package org.apache.james.mime4j.field;
 
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.dom.address.AddressList;
-import org.apache.james.mime4j.field.address.parser.AddressBuilder;
-import org.apache.james.mime4j.field.address.parser.ParseException;
+import org.apache.james.mime4j.field.address.AddressBuilder;
+import org.apache.james.mime4j.field.address.ParseException;
 import org.apache.james.mime4j.util.ByteSequence;
 
 /**

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/Fields.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/Fields.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/Fields.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/Fields.java Wed Jan 19 18:50:34 2011
@@ -50,7 +50,7 @@ import org.apache.james.mime4j.field.Dat
 import org.apache.james.mime4j.field.MailboxFieldImpl;
 import org.apache.james.mime4j.field.MailboxListFieldImpl;
 import org.apache.james.mime4j.field.UnstructuredFieldImpl;
-import org.apache.james.mime4j.field.address.formatter.AddressFormatter;
+import org.apache.james.mime4j.field.address.AddressFormatter;
 import org.apache.james.mime4j.stream.RawField;
 import org.apache.james.mime4j.util.MimeUtil;
 

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxFieldImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxFieldImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxFieldImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxFieldImpl.java Wed Jan 19 18:50:34 2011
@@ -22,8 +22,8 @@ package org.apache.james.mime4j.field;
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.dom.address.Mailbox;
 import org.apache.james.mime4j.dom.address.MailboxList;
-import org.apache.james.mime4j.field.address.parser.AddressBuilder;
-import org.apache.james.mime4j.field.address.parser.ParseException;
+import org.apache.james.mime4j.field.address.AddressBuilder;
+import org.apache.james.mime4j.field.address.ParseException;
 import org.apache.james.mime4j.util.ByteSequence;
 
 /**

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxListFieldImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxListFieldImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxListFieldImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/field/MailboxListFieldImpl.java Wed Jan 19 18:50:34 2011
@@ -21,8 +21,8 @@ package org.apache.james.mime4j.field;
 
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.dom.address.MailboxList;
-import org.apache.james.mime4j.field.address.parser.AddressBuilder;
-import org.apache.james.mime4j.field.address.parser.ParseException;
+import org.apache.james.mime4j.field.address.AddressBuilder;
+import org.apache.james.mime4j.field.address.ParseException;
 import org.apache.james.mime4j.util.ByteSequence;
 
 /**

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPart.java Wed Jan 19 18:50:34 2011
@@ -22,12 +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.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.ContentDispositionField;
 import org.apache.james.mime4j.dom.field.ContentTransferEncodingField;
 import org.apache.james.mime4j.dom.field.ContentTypeField;
@@ -39,7 +33,7 @@ import org.apache.james.mime4j.util.Mime
 /**
  * Represents a MIME body part  (see RFC 2045).
  */
-public class BodyPart extends Entity {
+public class BodyPart extends AbstractEntity {
 
     /**
      * Creates a new empty <code>BodyPart</code>.
@@ -47,39 +41,12 @@ public class BodyPart extends Entity {
     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 Header(other.getHeader()));
-        }
-
-        if (other.getBody() != null) {
-            Body bodyCopy = BodyCopier.copy(other.getBody());
-            setBody(bodyCopy);
-        }
-    }
-
 	@Override
 	protected String newUniqueBoundary() {
 		return MimeUtil.createUniqueBoundary();
 	}
 
+    @Override
     protected ContentDispositionField newContentDisposition(
             String dispositionType, String filename, long size,
             Date creationDate, Date modificationDate, Date readDate) {
@@ -87,29 +54,35 @@ public class BodyPart extends Entity {
                 creationDate, modificationDate, readDate);
     }
 
+    @Override
     protected ContentDispositionField newContentDisposition(
             String dispositionType, Map<String, String> parameters) {
         return Fields.contentDisposition(dispositionType, parameters);
     }
 
+    @Override
     protected ContentTypeField newContentType(String mimeType,
             Map<String, String> parameters) {
         return Fields.contentType(mimeType, parameters);
     }
 
+    @Override
     protected ContentTransferEncodingField newContentTransferEncoding(
             String contentTransferEncoding) {
         return Fields.contentTransferEncoding(contentTransferEncoding);
     }
 
+    @Override
     protected String calcTransferEncoding(ContentTransferEncodingField f) {
         return ContentTransferEncodingFieldImpl.getEncoding(f);
     }
 
+    @Override
     protected String calcMimeType(ContentTypeField child, ContentTypeField parent) {
         return ContentTypeFieldImpl.getMimeType(child, parent);
     }
 
+    @Override
     protected String calcCharset(ContentTypeField contentType) {
         return ContentTypeFieldImpl.getCharset(contentType); 
     }

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/EntityBuilder.java Wed Jan 19 18:50:34 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;
@@ -98,7 +98,7 @@ public class EntityBuilder implements Co
      * @see org.apache.james.mime4j.parser.ContentHandler#startHeader()
      */
     public void startHeader() throws MimeException {
-        stack.push(new Header());
+        stack.push(new HeaderImpl());
     }
     
     /**

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/HeaderImpl.java Wed Jan 19 18:50:34 2011
@@ -19,23 +19,10 @@
 
 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).
  */
-public class HeaderImpl extends Header {
+public class HeaderImpl extends AbstractHeader {
 
     /**
      * Creates a new empty <code>Header</code>.
@@ -43,50 +30,4 @@ public class HeaderImpl extends Header {
     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/trunk/dom/src/main/java/org/apache/james/mime4j/message/MaximalBodyDescriptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MaximalBodyDescriptor.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MaximalBodyDescriptor.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MaximalBodyDescriptor.java Wed Jan 19 18:50:34 2011
@@ -108,6 +108,7 @@ public class MaximalBodyDescriptor exten
         this.isContentMD5Set = false;
     }
 
+    @Override
     public MutableBodyDescriptor newChild() {
         return new MaximalBodyDescriptor(this, getDecodeMonitor());
     }

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilderImpl.java Wed Jan 19 18:50:34 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/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MessageImpl.java Wed Jan 19 18:50:34 2011
@@ -20,21 +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.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.address.Address;
 import org.apache.james.mime4j.dom.address.Mailbox;
 import org.apache.james.mime4j.dom.field.AddressListField;
@@ -49,22 +40,12 @@ 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 Message {
+public class MessageImpl extends AbstractMessage {
 
     /**
      * Creates a new empty <code>Message</code>.
@@ -73,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 Header(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 {
@@ -224,32 +65,39 @@ public class MessageImpl extends Message
         return MimeUtil.createUniqueBoundary();
     }
 
+    @Override
     protected UnstructuredField newMessageId(String hostname) {
         return Fields.messageId(hostname);
     }
 
+    @Override
     protected DateTimeField newDate(Date date, TimeZone zone) {
         return Fields.date(FieldName.DATE, date, zone);
     }
 
+    @Override
     protected MailboxField newMailbox(String fieldName, Mailbox mailbox) {
         return Fields.mailbox(fieldName, mailbox);
     }
 
+    @Override
     protected MailboxListField newMailboxList(String fieldName,
             Collection<Mailbox> mailboxes) {
         return Fields.mailboxList(fieldName, mailboxes);
     }
 
+    @Override
     protected AddressListField newAddressList(String fieldName,
             Collection<Address> addresses) {
         return Fields.addressList(fieldName, addresses);
     }
 
+    @Override
     protected UnstructuredField newSubject(String subject) {
         return Fields.subject(subject);
     }
 
+    @Override
     protected ContentDispositionField newContentDisposition(
             String dispositionType, String filename, long size,
             Date creationDate, Date modificationDate, Date readDate) {
@@ -257,29 +105,35 @@ public class MessageImpl extends Message
                 creationDate, modificationDate, readDate);
     }
 
+    @Override
     protected ContentDispositionField newContentDisposition(
             String dispositionType, Map<String, String> parameters) {
         return Fields.contentDisposition(dispositionType, parameters);
     }
 
+    @Override
     protected ContentTypeField newContentType(String mimeType,
             Map<String, String> parameters) {
         return Fields.contentType(mimeType, parameters);
     }
 
+    @Override
     protected ContentTransferEncodingField newContentTransferEncoding(
             String contentTransferEncoding) {
         return Fields.contentTransferEncoding(contentTransferEncoding);
     }
 
+    @Override
     protected String calcTransferEncoding(ContentTransferEncodingField f) {
         return ContentTransferEncodingFieldImpl.getEncoding(f);
     }
 
+    @Override
     protected String calcMimeType(ContentTypeField child, ContentTypeField parent) {
         return ContentTypeFieldImpl.getMimeType(child, parent);
     }
 
+    @Override
     protected String calcCharset(ContentTypeField contentType) {
         return ContentTypeFieldImpl.getCharset(contentType); 
     }

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartImpl.java Wed Jan 19 18:50:34 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;
 
@@ -33,7 +29,7 @@ import org.apache.james.mime4j.util.Cont
  * first body part while the epilogue consists of whatever characters come after
  * the last body part.
  */
-public class MultipartImpl extends Multipart {
+public class MultipartImpl extends AbstractMultipart {
 
     private ByteSequence preamble;
     private transient String preambleStrCache;
@@ -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;
@@ -110,6 +67,7 @@ public class MultipartImpl extends Multi
      * 
      * @return the preamble.
      */
+    @Override
     public String getPreamble() {
         if (!preambleComputed) {
             preambleStrCache = preamble != null ? ContentUtil.decode(preamble) : null;
@@ -124,6 +82,7 @@ public class MultipartImpl extends Multi
      * @param preamble
      *            the preamble.
      */
+    @Override
     public void setPreamble(String preamble) {
         this.preamble = preamble != null ? ContentUtil.encode(preamble) : null;
         this.preambleStrCache = preamble;
@@ -146,6 +105,7 @@ public class MultipartImpl extends Multi
      * 
      * @return the epilogue.
      */
+    @Override
     public String getEpilogue() {
         if (!epilogueComputed) {
             epilogueStrCache = epilogue != null ? ContentUtil.decode(epilogue) : null;
@@ -160,6 +120,7 @@ public class MultipartImpl extends Multi
      * @param epilogue
      *            the epilogue.
      */
+    @Override
     public void setEpilogue(String epilogue) {
         this.epilogue = epilogue != null ? ContentUtil.encode(epilogue) : null;
         this.epilogueStrCache = epilogue;

Modified: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java?rev=1060898&r1=1060897&r2=1060898&view=diff
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java (original)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java Wed Jan 19 18:50:34 2011
@@ -61,7 +61,7 @@ public abstract class SimpleContentHandl
      */
     @Override
     public final void startHeader() {
-        currHeader = new Header();
+        currHeader = new HeaderImpl();
     }
 
     /**