Before I file another MIME4J issue I would like to ask your opinion.

At the moment we use Sun's JavaMail API to process and manipulate e-mails. I
would like to go away from JavaMail so I am currently evaluating MIME4J to
see if is an alternative. So far it looks very promising.

Our use case is typically the following: parse an incoming message; run the
message through a workflow that manipulates it (can be: apply a signature,
add/remove/replace an attachment, etc.); re-send and/or archive the message.

Now the problem is that I would basically like to create a new Message
object that should contain some parts from the original message and some new
parts. The original message should not modified though. In other words I
would like to create a Message that shares some Part objects with another
Message.

Currently this is not possible because Part holds a reference to a parent
Entity (getParent() and setParent()) and a Part can of course have only one
parent.

So the question is do you think it would be possible to remove this parent
reference?

In the current release the parent entity is used for two purposes:
1) determine the message boundary and charset in Multipart.writeTo()
2) in Entity.getMimeType() to ask the parent if the entity does not have a
Content-Type header field.

Number one could be resolved by adding an "Entity parent" parameter to
Body.writeTo(). But I am not sure about number two. Would it suffice to
return null instead of delegating to a parent entity?

I have attached a patch for #1 to illustrate what I mean. Hope it gets
through the mailing list..

Markus
Index: src/test/java/org/apache/james/mime4j/message/MessageParserTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MessageParserTest.java	(revision 698697)
+++ src/test/java/org/apache/james/mime4j/message/MessageParserTest.java	(working copy)
@@ -193,7 +193,7 @@
             try {
                 expected = new BufferedInputStream(new FileInputStream(expectedFile));
             } catch (FileNotFoundException ex) {
-                writeToFile(b, mime4jFile);
+                writeToFile(e, b, mime4jFile);
                 fail("Test file not found. Generated the expected result with mime4j prefix: "+ex.getMessage());
             }
             
@@ -212,7 +212,7 @@
                             ((BinaryBody) b).getInputStream());
                 }
             } catch (AssertionError er) {
-                writeToFile(b, mime4jFile);
+                writeToFile(e, b, mime4jFile);
                 throw er;
             }
         }
@@ -227,10 +227,10 @@
         return sb.toString();
     }
 
-    private void writeToFile(Body b, File mime4jFile)
+    private void writeToFile(Entity parent, Body b, File mime4jFile)
             throws FileNotFoundException, IOException {
         if (b instanceof TextBody) {
-            String charset = CharsetUtil.toJavaCharset(b.getParent().getCharset());
+            String charset = CharsetUtil.toJavaCharset(parent.getCharset());
             if (charset == null) {
                 charset = "ISO8859-1";
             }
Index: src/test/java/org/apache/james/mime4j/message/MessageTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MessageTest.java	(revision 698697)
+++ src/test/java/org/apache/james/mime4j/message/MessageTest.java	(working copy)
@@ -71,7 +71,6 @@
         
         parent = new Message();
         child = new Message();
-        child.setParent(parent);
         parent.setHeader(headerMultipartDigest);
         child.setHeader(headerEmpty);
         assertEquals("multipart/digest, empty", "message/rfc822", 
@@ -85,7 +84,6 @@
         
         parent = new Message();
         child = new Message();
-        child.setParent(parent);
         parent.setHeader(headerMultipartMixed);
         child.setHeader(headerEmpty);
         assertEquals("multipart/mixed, empty", "text/plain", 
Index: src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java	(revision 698697)
+++ src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java	(working copy)
@@ -47,7 +47,6 @@
         message.setHeader(header);
         
         Multipart multipart = new Multipart("alternative");
-        multipart.setParent(message);
         BodyPart p1 = new BodyPart();
         Header h1 = new Header();
         h1.addField(Field.parse("Content-Type: text/plain"));
@@ -69,7 +68,7 @@
         multipart.addBodyPart(p3);
         
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        multipart.writeTo(out, MessageUtils.LENIENT);
+        multipart.writeTo(message, out, MessageUtils.LENIENT);
         out.close();
         
         String expected = "\r\n" + 
@@ -115,7 +114,7 @@
             return new StringReader(this.text);
         }
 
-        public void writeTo(final OutputStream out, int mode) throws IOException {
+        public void writeTo(Entity parent, final OutputStream out, int mode) throws IOException {
             if (out == null) {
                 throw new IllegalArgumentException("Output stream may not be null");
             }
Index: src/main/java/org/apache/james/mime4j/message/Entity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Entity.java	(revision 698697)
+++ src/main/java/org/apache/james/mime4j/message/Entity.java	(working copy)
@@ -39,29 +39,8 @@
 public abstract class Entity implements Disposable {
     private Header header = null;
     private Body body = null;
-    private Entity parent = null;
-
-    /**
-     * 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;
-    }
     
     /**
-     * Sets the parent entity of this entity.
-     * 
-     * @param parent the parent entity or <code>null</code> if
-     *        this will be the root entity.
-     */
-    public void setParent(Entity parent) {
-        this.parent = parent;
-    }
-    
-    /**
      * Gets the entity header.
      * 
      * @return the header.
@@ -95,7 +74,6 @@
      */
     public void setBody(Body body) {
         this.body = body;
-        body.setParent(this);
     }
     
     /**
@@ -106,12 +84,13 @@
      * @return the MIME type.
      */
     public String getMimeType() {
+        // FIXME: currently broken
         ContentTypeField child = 
             (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
-        ContentTypeField parent = getParent() != null 
+        ContentTypeField parent = /*getParent() != null 
             ? (ContentTypeField) getParent().getHeader().
                                                 getField(Field.CONTENT_TYPE)
-            : null;
+            :*/ null;
         
         return ContentTypeField.getMimeType(child, parent);
     }
@@ -164,6 +143,11 @@
             && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
     }
     
+    public void writeTo(OutputStream out, int mode) throws IOException,
+            MimeException {
+        writeTo(null, out, mode);
+    }    
+
     /**
      * Write the content to the given outputstream
      * 
@@ -172,7 +156,7 @@
      *   [EMAIL PROTECTED] MessageUtils#LENIENT}, [EMAIL PROTECTED] MessageUtils#STRICT_ERROR}, [EMAIL PROTECTED] MessageUtils#STRICT_IGNORE}  
      * @throws IOException 
      */
-    public void writeTo(OutputStream out, int mode) throws IOException, MimeException {
+    public void writeTo(Entity parent, OutputStream out, int mode) throws IOException, MimeException {
         getHeader().writeTo(out, mode);
         
         out.flush();
@@ -187,7 +171,7 @@
         } else {
             encOut = out;
         }
-        body.writeTo(encOut, mode);
+        body.writeTo(this, encOut, mode);
         encOut.flush();
         // the Base64 output streams requires closing of the stream but
         // we don't want it to close the inner stream so we override the behaviour
Index: src/main/java/org/apache/james/mime4j/message/Multipart.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Multipart.java	(revision 698697)
+++ src/main/java/org/apache/james/mime4j/message/Multipart.java	(working copy)
@@ -49,7 +49,6 @@
     private String preamble = "";
     private String epilogue = "";
     private List bodyParts = new LinkedList();
-    private Entity parent = null;
     private String subType;
 
     /**
@@ -80,23 +79,6 @@
     public void setSubType(String subType) {
         this.subType = subType;
     }
-    
-    /**
-     * @see org.apache.james.mime4j.message.Body#getParent()
-     */
-    public Entity getParent() {
-        return parent;
-    }
-    
-    /**
-     * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
-     */
-    public void setParent(Entity parent) {
-        this.parent = parent;
-        for (Iterator it = bodyParts.iterator(); it.hasNext();) {
-            ((BodyPart) it.next()).setParent(parent);
-        }
-    }
 
     /**
      * Gets the epilogue.
@@ -132,9 +114,6 @@
      */
     public void setBodyParts(List bodyParts) {
         this.bodyParts = bodyParts;
-        for (Iterator it = bodyParts.iterator(); it.hasNext();) {
-            ((BodyPart) it.next()).setParent(parent);
-        }
     }
     
     /**
@@ -144,7 +123,6 @@
      */
     public void addBodyPart(BodyPart bodyPart) {
         bodyParts.add(bodyPart);
-        bodyPart.setParent(parent);
     }
     
     /**
@@ -174,9 +152,8 @@
      * @throws IOException if case of an I/O error
      * @throws MimeException if case of a MIME protocol violation
      */
-    public void writeTo(final OutputStream out, int mode) throws IOException, MimeException {
-        Entity e = getParent();
-        
+    public void writeTo(Entity parent, final OutputStream out, int mode) throws IOException, MimeException {
+        Entity e = parent;
         ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
                 Field.CONTENT_TYPE);
         if (cField == null || cField.getBoundary() == null) {
@@ -209,7 +186,7 @@
             writer.write(MessageUtils.CRLF);
             writer.flush();
             final BodyPart bodyPart = (BodyPart) bodyParts.get(i);
-            bodyPart.writeTo(out, mode);
+            bodyPart.writeTo(parent, out, mode);
             writer.write(MessageUtils.CRLF);
         }
 
Index: src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java	(revision 698697)
+++ src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java	(working copy)
@@ -103,7 +103,7 @@
     /**
      * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
      */
-    public void writeTo(OutputStream out, int mode) throws IOException {
+    public void writeTo(Entity parent, OutputStream out, int mode) throws IOException {
         final InputStream inputStream = tempFile.getInputStream();
         CodecUtil.copy(inputStream,out);
     }
Index: src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java	(revision 698697)
+++ src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java	(working copy)
@@ -80,7 +80,7 @@
     /**
      * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
      */
-    public void writeTo(OutputStream out, int mode) throws IOException {
+    public void writeTo(Entity parent, OutputStream out, int mode) throws IOException {
         final InputStream inputStream = getInputStream();
         CodecUtil.copy(inputStream,out);
     }
Index: src/main/java/org/apache/james/mime4j/message/Body.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Body.java	(revision 698697)
+++ src/main/java/org/apache/james/mime4j/message/Body.java	(working copy)
@@ -34,20 +34,6 @@
 public interface Body extends Disposable {
 
     /**
-     * Gets the parent of this body.
-     * 
-     * @return the parent.
-     */
-    Entity getParent();
-    
-    /**
-     * Sets the parent of this body.
-     * 
-     * @param parent the parent.
-     */
-    void setParent(Entity parent);
-    
-    /**
      * Writes this body to the given stream in MIME message format.
      * 
      * @param out the stream to write to.
@@ -55,5 +41,5 @@
      *   [EMAIL PROTECTED] MessageUtils#LENIENT}, [EMAIL PROTECTED] MessageUtils#STRICT_ERROR}, [EMAIL PROTECTED] MessageUtils#STRICT_IGNORE}  
      * @throws IOException on I/O errors.
      */
-    void writeTo(OutputStream out, int mode) throws IOException, MimeException;
+    void writeTo(Entity parent, OutputStream out, int mode) throws IOException, MimeException;
 }
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to