This patch should illustrate how I think copying a message could be done. It
is only a sketch - there is no JavaDoc and no unit tests. But at least we
have something more concrete to talk about. A few lines of code might say
more than a thousand words..
Here are some details: the public classes Message, Multipart, Entity and
BodyPart all have a public copy constructor. The interface Body has a method
getCopy() that is used by the copy constructors.
Please let me know what you think of this.
Markus
Index: src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java (revision 700849)
+++ src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java (working copy)
@@ -111,6 +111,10 @@
this(text, null);
}
+ public Body getCopy() {
+ return new StringPart(text, charset);
+ }
+
public Reader getReader() throws IOException {
return new StringReader(this.text);
}
Index: src/main/java/org/apache/james/mime4j/message/Entity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Entity.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/Entity.java (working copy)
@@ -41,6 +41,19 @@
private Body body = null;
private Entity parent = null;
+ protected Entity() {
+ }
+
+ protected Entity(Entity other) {
+ parent = null;
+ if (other.header != null)
+ header = new Header(other.header);
+ if (other.body != null) {
+ body = other.body.getCopy();
+ body.setParent(this);
+ }
+ }
+
/**
* Gets the parent entity of this entity.
* Returns <code>null</code> if this is the root entity.
Index: src/main/java/org/apache/james/mime4j/message/Multipart.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Multipart.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/Multipart.java (working copy)
@@ -59,6 +59,25 @@
this.subType = subType;
}
+ public Multipart(Multipart other) {
+ preamble = other.preamble;
+ epilogue = other.epilogue;
+ parent = null;
+ subType = other.subType;
+
+ bodyParts = new LinkedList();
+ for (Iterator iter = other.bodyParts.iterator(); iter.hasNext();) {
+ BodyPart otherBodyPart = (BodyPart) iter.next();
+ BodyPart copy = new BodyPart(otherBodyPart);
+ bodyParts.add(copy);
+ copy.setParent(parent);
+ }
+ }
+
+ public Body getCopy() {
+ return new Multipart(this);
+ }
+
/**
* Gets the multipart sub-type. E.g. <code>alternative</code> (the default)
* or <code>parallel</code>. See RFC 2045 for common sub-types and their
Index: src/main/java/org/apache/james/mime4j/message/BodyPart.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/BodyPart.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/BodyPart.java (working copy)
@@ -29,4 +29,11 @@
*/
public class BodyPart extends Entity {
+ public BodyPart() {
+ }
+
+ public BodyPart(BodyPart other) {
+ super(other);
+ }
+
}
Index: src/main/java/org/apache/james/mime4j/message/Message.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Message.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/Message.java (working copy)
@@ -72,7 +72,15 @@
public Message(InputStream is) throws IOException {
this(is, null);
}
-
+
+ public Message(Message other) {
+ super(other);
+ }
+
+ public Body getCopy() {
+ return new Message(this);
+ }
+
/**
* Gets the <code>Subject</code> field.
*
Index: src/main/java/org/apache/james/mime4j/message/Header.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Header.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/Header.java (working copy)
@@ -30,6 +30,8 @@
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.field.ContentTypeField;
@@ -57,6 +59,17 @@
public Header() {
}
+ public Header(Header other) {
+ fields = new LinkedList(other.fields);
+ fieldMap = new HashMap();
+ for (Iterator iter = other.fieldMap.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = (Entry) iter.next();
+ String name = (String) entry.getKey();
+ List fields = (List) entry.getValue();
+ fieldMap.put(name, fields);
+ }
+ }
+
/**
* Creates a new <code>Header</code> from the specified stream.
*
Index: src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java (working copy)
@@ -37,8 +37,8 @@
*/
class TempFileBinaryBody extends AbstractBody implements BinaryBody {
- private Entity parent = null;
private TempFile tempFile = null;
+ private ReferenceCounter refCounter = new ReferenceCounter();
/**
* Use the given InputStream to build the TemporyFileBinaryBody
@@ -55,22 +55,18 @@
CodecUtil.copy(is, out);
out.close();
}
+
+ public TempFileBinaryBody(TempFileBinaryBody other) {
+ tempFile = other.tempFile;
+ refCounter = other.refCounter;
+ refCounter.increment();
+ }
- /**
- * @see org.apache.james.mime4j.message.AbstractBody#getParent()
- */
- public Entity getParent() {
- return parent;
+ public Body getCopy() {
+ return new TempFileBinaryBody(this);
}
-
+
/**
- * @see org.apache.james.mime4j.message.AbstractBody#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- this.parent = parent;
- }
-
- /**
* @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
*/
public InputStream getInputStream() throws IOException {
@@ -91,6 +87,7 @@
* @see org.apache.james.mime4j.message.Disposable#dispose()
*/
public void dispose() {
- tempFile.delete();
+ if (refCounter.decrement())
+ tempFile.delete();
}
}
Index: src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java (working copy)
@@ -46,6 +46,7 @@
private String mimeCharset = null;
private TempFile tempFile = null;
+ private ReferenceCounter refCounter = new ReferenceCounter();
public TempFileTextBody(final InputStream is, final String mimeCharset) throws IOException {
@@ -58,6 +59,17 @@
out.close();
}
+ public TempFileTextBody(TempFileTextBody other) {
+ mimeCharset = other.mimeCharset;
+ tempFile = other.tempFile;
+ refCounter = other.refCounter;
+ refCounter.increment();
+ }
+
+ public Body getCopy() {
+ return new TempFileTextBody(this);
+ }
+
/**
* @see org.apache.james.mime4j.message.TextBody#getReader()
*/
@@ -114,6 +126,7 @@
* @see org.apache.james.mime4j.message.Disposable#dispose()
*/
public void dispose() {
- tempFile.delete();
+ if (refCounter.decrement())
+ tempFile.delete();
}
}
Index: src/main/java/org/apache/james/mime4j/message/Body.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Body.java (revision 700849)
+++ src/main/java/org/apache/james/mime4j/message/Body.java (working copy)
@@ -33,6 +33,8 @@
*/
public interface Body extends Disposable {
+ Body getCopy();
+
/**
* Gets the parent of this body.
*
Index: src/main/java/org/apache/james/mime4j/message/ReferenceCounter.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/ReferenceCounter.java (revision 0)
+++ src/main/java/org/apache/james/mime4j/message/ReferenceCounter.java (revision 0)
@@ -0,0 +1,13 @@
+package org.apache.james.mime4j.message;
+
+class ReferenceCounter {
+ int counter = 1;
+
+ public void increment() {
+ ++counter;
+ }
+
+ public boolean decrement() {
+ return --counter == 0;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]