Extended new builder classes with methods to create copies of message elements and to parse message from content stream
git-svn-id: https://svn.apache.org/repos/asf/james/mime4j/trunk@1611278 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dom/src/main/java/org/apache/james/mime4j/message/AbstractEntityBuilder.java b/dom/src/main/java/org/apache/james/mime4j/message/AbstractEntityBuilder.java
index 7fb9fb2..434a47f 100644
--- a/dom/src/main/java/org/apache/james/mime4j/message/AbstractEntityBuilder.java
+++ b/dom/src/main/java/org/apache/james/mime4j/message/AbstractEntityBuilder.java
@@ -19,8 +19,6 @@
package org.apache.james.mime4j.message;
-import java.io.IOException;
-import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@@ -39,7 +37,6 @@
import org.apache.james.mime4j.dom.field.FieldName;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.field.Fields;
-import org.apache.james.mime4j.io.InputStreams;
import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.NameValuePair;
import org.apache.james.mime4j.util.MimeUtil;
@@ -51,8 +48,6 @@
private Body body;
- private BodyFactory bodyFactory;
-
AbstractEntityBuilder() {
this.fields = new LinkedList<Field>();
this.fieldMap = new HashMap<String, List<Field>>();
@@ -189,6 +184,15 @@
return this;
}
+ /**
+ * Clears all fields.
+ */
+ public AbstractEntityBuilder clearFields() {
+ fields.clear();
+ fieldMap.clear();
+ return this;
+ }
+
@SuppressWarnings("unchecked")
<F extends ParsedField> F obtainField(String fieldName) {
return (F) getField(fieldName);
@@ -454,59 +458,6 @@
}
/**
- * Sets {@link org.apache.james.mime4j.message.BodyFactory} that will be
- * used to generate message body.
- *
- * @param bodyFactory body factory.
- */
- public AbstractEntityBuilder use(final BodyFactory bodyFactory) {
- this.bodyFactory = bodyFactory;
- return this;
- }
-
- /**
- * Sets text of this message with the charset.
- *
- * @param text
- * the text.
- * @param charset
- * the charset of the text.
- */
- public AbstractEntityBuilder setBody(String text, Charset charset) throws IOException {
- return setBody(text, null, charset);
- }
-
- /**
- * Sets text of this message with the given MIME subtype and charset.
- *
- * @param text
- * the text.
- * @param charset
- * the charset of the text.
- * @param subtype
- * the text subtype (e.g. "plain", "html" or
- * "xml").
- */
- public AbstractEntityBuilder setBody(String text, String subtype, Charset charset) throws IOException {
- if (subtype != null) {
- if (charset != null) {
- setField(Fields.contentType("text/" + subtype, new NameValuePair("charset", charset.name())));
- } else {
- setField(Fields.contentType("text/" + subtype));
- }
- }
- TextBody textBody;
- if (bodyFactory != null) {
- textBody = bodyFactory.textBody(
- InputStreams.create(text, charset),
- charset != null ? charset.name() : null);
- } else {
- textBody = BasicBodyFactory.INSTANCE.textBody(text, charset);
- }
- return setBody(textBody);
- }
-
- /**
* Returns message body.
*
* @return the message body.
diff --git a/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java b/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
index 4b76cb3..066efe3 100644
--- a/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
+++ b/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
@@ -23,8 +23,11 @@
import java.nio.charset.Charset;
import java.util.Date;
+import org.apache.james.mime4j.dom.BinaryBody;
import org.apache.james.mime4j.dom.Body;
-import org.apache.james.mime4j.dom.Header;
+import org.apache.james.mime4j.dom.TextBody;
+import org.apache.james.mime4j.field.Fields;
+import org.apache.james.mime4j.io.InputStreams;
import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.NameValuePair;
@@ -33,10 +36,23 @@
*/
public class BodyPartBuilder extends AbstractEntityBuilder {
+ private BodyFactory bodyFactory;
+
public static BodyPartBuilder create() {
return new BodyPartBuilder();
}
+ /**
+ * Sets {@link org.apache.james.mime4j.message.BodyFactory} that will be
+ * used to generate message body.
+ *
+ * @param bodyFactory body factory.
+ */
+ public BodyPartBuilder use(BodyFactory bodyFactory) {
+ this.bodyFactory = bodyFactory;
+ return this;
+ }
+
@Override
public BodyPartBuilder setField(Field field) {
super.setField(field);
@@ -102,22 +118,68 @@
return this;
}
- @Override
- public BodyPartBuilder use(final BodyFactory bodyFactory) {
- super.use(bodyFactory);
- return this;
- }
-
- @Override
+ /**
+ * Sets text of this message with the charset.
+ *
+ * @param text
+ * the text.
+ * @param charset
+ * the charset of the text.
+ */
public BodyPartBuilder setBody(String text, Charset charset) throws IOException {
- super.setBody(text, charset);
- return this;
+ return setBody(text, null, charset);
}
- @Override
+ /**
+ * Sets text of this message with the given MIME subtype and charset.
+ *
+ * @param text
+ * the text.
+ * @param charset
+ * the charset of the text.
+ * @param subtype
+ * the text subtype (e.g. "plain", "html" or
+ * "xml").
+ */
public BodyPartBuilder setBody(String text, String subtype, Charset charset) throws IOException {
- super.setBody(text, subtype, charset);
- return this;
+ if (subtype != null) {
+ if (charset != null) {
+ setField(Fields.contentType("text/" + subtype, new NameValuePair("charset", charset.name())));
+ } else {
+ setField(Fields.contentType("text/" + subtype));
+ }
+ }
+ TextBody textBody;
+ if (bodyFactory != null) {
+ textBody = bodyFactory.textBody(
+ InputStreams.create(text, charset),
+ charset != null ? charset.name() : null);
+ } else {
+ textBody = BasicBodyFactory.INSTANCE.textBody(text, charset);
+ }
+ return setBody(textBody);
+ }
+
+ /**
+ * Sets binary content of this message with the given MIME type.
+ *
+ * @param body
+ * the body.
+ * @param mimeType
+ * the MIME media type of the specified body
+ * ("type/subtype").
+ */
+ public BodyPartBuilder setBody(byte[] bin, String mimeType) throws IOException {
+ if (mimeType != null) {
+ setField(Fields.contentType(mimeType));
+ }
+ BinaryBody binBody;
+ if (bodyFactory != null) {
+ binBody = bodyFactory.binaryBody(InputStreams.create(bin));
+ } else {
+ binBody = BasicBodyFactory.INSTANCE.binaryBody(bin);
+ }
+ return setBody(binBody);
}
public BodyPart build() {
diff --git a/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java b/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java
index 9a332af..1f163cb 100644
--- a/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java
+++ b/dom/src/main/java/org/apache/james/mime4j/message/MessageBuilder.java
@@ -20,6 +20,7 @@
package org.apache.james.mime4j.message;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
@@ -29,9 +30,17 @@
import java.util.List;
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.BinaryBody;
import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.dom.FieldParser;
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.TextBody;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.AddressList;
import org.apache.james.mime4j.dom.address.Mailbox;
@@ -43,9 +52,15 @@
import org.apache.james.mime4j.dom.field.MailboxListField;
import org.apache.james.mime4j.dom.field.ParseException;
import org.apache.james.mime4j.dom.field.UnstructuredField;
+import org.apache.james.mime4j.field.DefaultFieldParser;
import org.apache.james.mime4j.field.Fields;
+import org.apache.james.mime4j.field.LenientFieldParser;
import org.apache.james.mime4j.field.address.AddressBuilder;
+import org.apache.james.mime4j.io.InputStreams;
+import org.apache.james.mime4j.parser.MimeStreamParser;
+import org.apache.james.mime4j.stream.BodyDescriptorBuilder;
import org.apache.james.mime4j.stream.Field;
+import org.apache.james.mime4j.stream.MimeConfig;
import org.apache.james.mime4j.stream.NameValuePair;
/**
@@ -53,10 +68,112 @@
*/
public class MessageBuilder extends AbstractEntityBuilder {
+ private MimeConfig config;
+ private DecodeMonitor monitor;
+ private BodyDescriptorBuilder bodyDescBuilder;
+ private FieldParser<?> fieldParser;
+ private BodyFactory bodyFactory;
+ private boolean flatMode;
+ private boolean rawContent;
+
public static MessageBuilder create() {
return new MessageBuilder();
}
+ public static MessageBuilder createCopy(Message other) {
+ return new MessageBuilder().copy(other);
+ }
+
+ public static MessageBuilder read(final InputStream is) throws IOException {
+ return new MessageBuilder().parse(is);
+ }
+
+ /**
+ * Sets MIME configuration.
+ *
+ * @param config the configuration.
+ */
+ public MessageBuilder use(MimeConfig config) {
+ this.config = config;
+ return this;
+ }
+
+ /**
+ * Sets {@link org.apache.james.mime4j.codec.DecodeMonitor} that will be
+ * used to handle malformed data when executing {@link #parse(java.io.InputStream)}.
+ *
+ * @param monitor the decoder monitor.
+ */
+ public MessageBuilder use(DecodeMonitor monitor) {
+ this.monitor = monitor;
+ return this;
+ }
+
+ /**
+ * Sets {@link org.apache.james.mime4j.stream.BodyDescriptorBuilder} that will be
+ * used to generate body descriptors when executing {@link #parse(java.io.InputStream)}.
+ *
+ * @param bodyDescBuilder the body descriptor builder.
+ */
+ public MessageBuilder use(BodyDescriptorBuilder bodyDescBuilder) {
+ this.bodyDescBuilder = bodyDescBuilder;
+ return this;
+ }
+
+ /**
+ * Sets {@link org.apache.james.mime4j.dom.FieldParser} that will be
+ * used to generate parse message fields when executing {@link #parse(java.io.InputStream)}.
+ *
+ * @param fieldParser the field parser.
+ */
+ public MessageBuilder use(FieldParser<?> fieldParser) {
+ this.fieldParser = fieldParser;
+ return this;
+ }
+
+ /**
+ * Sets {@link org.apache.james.mime4j.message.BodyFactory} that will be
+ * used to generate message body.
+ *
+ * @param bodyFactory the body factory.
+ */
+ public MessageBuilder use(BodyFactory bodyFactory) {
+ this.bodyFactory = bodyFactory;
+ return this;
+ }
+
+ /**
+ * Enables flat parsing mode for {@link #parse(java.io.InputStream)} operation.
+ */
+ public MessageBuilder enableFlatMode() {
+ this.flatMode = true;
+ return this;
+ }
+
+ /**
+ * Disables flat parsing mode for {@link #parse(java.io.InputStream)} operation.
+ */
+ public MessageBuilder disableFlatMode() {
+ this.flatMode = false;
+ return this;
+ }
+
+ /**
+ * Enables automatic content decoding for {@link #parse(java.io.InputStream)} operation.
+ */
+ public MessageBuilder enableContentDecoding() {
+ this.rawContent = false;
+ return this;
+ }
+
+ /**
+ * Enables disable content decoding for {@link #parse(java.io.InputStream)} operation.
+ */
+ public MessageBuilder disableContentDecoding() {
+ this.rawContent = true;
+ return this;
+ }
+
@Override
public MessageBuilder setField(Field field) {
super.setField(field);
@@ -76,6 +193,12 @@
}
@Override
+ public AbstractEntityBuilder clearFields() {
+ super.clearFields();
+ return this;
+ }
+
+ @Override
public MessageBuilder setContentTransferEncoding(String contentTransferEncoding) {
super.setContentTransferEncoding(contentTransferEncoding);
return this;
@@ -118,22 +241,68 @@
return this;
}
- @Override
- public MessageBuilder use(final BodyFactory bodyFactory) {
- super.use(bodyFactory);
- return this;
- }
-
- @Override
+ /**
+ * Sets text of this message with the charset.
+ *
+ * @param text
+ * the text.
+ * @param charset
+ * the charset of the text.
+ */
public MessageBuilder setBody(String text, Charset charset) throws IOException {
- super.setBody(text, charset);
- return this;
+ return setBody(text, null, charset);
}
- @Override
+ /**
+ * Sets text of this message with the given MIME subtype and charset.
+ *
+ * @param text
+ * the text.
+ * @param charset
+ * the charset of the text.
+ * @param subtype
+ * the text subtype (e.g. "plain", "html" or
+ * "xml").
+ */
public MessageBuilder setBody(String text, String subtype, Charset charset) throws IOException {
- super.setBody(text, subtype, charset);
- return this;
+ if (subtype != null) {
+ if (charset != null) {
+ setField(Fields.contentType("text/" + subtype, new NameValuePair("charset", charset.name())));
+ } else {
+ setField(Fields.contentType("text/" + subtype));
+ }
+ }
+ TextBody textBody;
+ if (bodyFactory != null) {
+ textBody = bodyFactory.textBody(
+ InputStreams.create(text, charset),
+ charset != null ? charset.name() : null);
+ } else {
+ textBody = BasicBodyFactory.INSTANCE.textBody(text, charset);
+ }
+ return setBody(textBody);
+ }
+
+ /**
+ * Sets binary content of this message with the given MIME type.
+ *
+ * @param body
+ * the body.
+ * @param mimeType
+ * the MIME media type of the specified body
+ * ("type/subtype").
+ */
+ public MessageBuilder setBody(byte[] bin, String mimeType) throws IOException {
+ if (mimeType != null) {
+ setField(Fields.contentType(mimeType));
+ }
+ BinaryBody binBody;
+ if (bodyFactory != null) {
+ binBody = bodyFactory.binaryBody(InputStreams.create(bin));
+ } else {
+ binBody = BasicBodyFactory.INSTANCE.binaryBody(bin);
+ }
+ return setBody(binBody);
}
/**
@@ -676,9 +845,65 @@
return this;
}
+ public MessageBuilder copy(Message other) {
+ if (other == null) {
+ return this;
+ }
+ clearFields();
+ final Header otherHeader = other.getHeader();
+ if (otherHeader != null) {
+ final List<Field> otherFields = otherHeader.getFields();
+ for (Field field: otherFields) {
+ addField(field);
+ }
+ }
+ Body body = null;
+ Body otherBody = other.getBody();
+ if (otherBody instanceof Message) {
+ body = MessageBuilder.createCopy((Message) otherBody).build();
+ } else if (otherBody instanceof Multipart) {
+ body = MultipartBuilder.createCopy((Multipart) otherBody).build();
+ } else if (otherBody instanceof SingleBody) {
+ body = ((SingleBody) otherBody).copy();
+ }
+ setBody(body);
+ return this;
+ }
+
+ public MessageBuilder parse(final InputStream is) throws IOException {
+ MimeConfig currentConfig = config != null ? config : MimeConfig.DEFAULT;
+ boolean strict = currentConfig.isStrictParsing();
+ DecodeMonitor currentMonitor = monitor != null ? monitor : strict ? DecodeMonitor.STRICT : DecodeMonitor.SILENT;
+ BodyDescriptorBuilder currentBodyDescBuilder = bodyDescBuilder != null ? bodyDescBuilder :
+ new DefaultBodyDescriptorBuilder(null, fieldParser != null ? fieldParser :
+ strict ? DefaultFieldParser.getParser() : LenientFieldParser.getParser(), currentMonitor);
+ BodyFactory currentBodyFactory = bodyFactory != null ? bodyFactory : new BasicBodyFactory();
+ MimeStreamParser parser = new MimeStreamParser(currentConfig, currentMonitor, currentBodyDescBuilder);
+
+ Message message = new MessageImpl();
+ parser.setContentHandler(new EntityBuilder(message, currentBodyFactory));
+ parser.setContentDecoding(!rawContent);
+ if (flatMode) {
+ parser.setFlat();
+ }
+ try {
+ parser.parse(is);
+ } catch (MimeException e) {
+ throw new MimeIOException(e);
+ }
+ clearFields();
+ final List<Field> fields = message.getHeader().getFields();
+ for (Field field: fields) {
+ addField(field);
+ }
+ setBody(message.getBody());
+ return this;
+ }
+
public Message build() {
MessageImpl message = new MessageImpl();
- Header header = message.getHeader();
+ HeaderImpl header = new HeaderImpl();
+ message.setHeader(header);
if (!containsField(FieldName.MIME_VERSION)) {
header.setField(Fields.version("1.0"));
}
diff --git a/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java b/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
index b2d956f..226ad93 100644
--- a/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
+++ b/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
@@ -19,12 +19,22 @@
package org.apache.james.mime4j.message;
+import java.io.IOException;
+import java.nio.charset.Charset;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import org.apache.james.mime4j.Charsets;
+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.TextBody;
+import org.apache.james.mime4j.io.InputStreams;
+import org.apache.james.mime4j.stream.Field;
/**
* {@link org.apache.james.mime4j.dom.Multipart} builder.
@@ -36,10 +46,16 @@
private String preamble;
private String epilogue;
+ private BodyFactory bodyFactory;
+
public static MultipartBuilder create(String subType) {
return new MultipartBuilder().setSubType(subType);
}
+ public static MultipartBuilder createCopy(Multipart other) {
+ return new MultipartBuilder().copy(other);
+ }
+
public static MultipartBuilder create() {
return new MultipartBuilder();
}
@@ -48,6 +64,11 @@
this.bodyParts = new LinkedList<Entity>();
}
+ public MultipartBuilder use(final BodyFactory bodyFactory) {
+ this.bodyFactory = bodyFactory;
+ return this;
+ }
+
/**
* Gets the multipart sub-type. E.g. <code>alternative</code> (the
* default) or <code>parallel</code>. See RFC 2045 for common sub-types
@@ -194,6 +215,53 @@
return this;
}
+ public MultipartBuilder addTextPart(String text, Charset charset) throws IOException {
+ Charset cs = charset != null ? charset : Charsets.ISO_8859_1;
+ TextBody body = bodyFactory != null ? bodyFactory.textBody(
+ InputStreams.create(text, cs), cs.name()) : BasicBodyFactory.INSTANCE.textBody(text, cs);
+ BodyPart bodyPart = new BodyPart();
+ bodyPart.setText(body);
+ bodyPart.setContentTransferEncoding("quoted-printable");
+
+ return addBodyPart(bodyPart);
+ }
+
+ public MultipartBuilder copy(Multipart other) {
+ if (other == null) {
+ return this;
+ }
+ subType = other.getSubType();
+ bodyParts.clear();
+ final List<Entity> otherParts = other.getBodyParts();
+ for (Entity otherPart: otherParts) {
+ BodyPart bodyPart = new BodyPart();
+ Header otherHeader = otherPart.getHeader();
+ if (otherHeader != null) {
+ HeaderImpl header = new HeaderImpl();
+ for (Field otherField : otherHeader.getFields()) {
+ header.addField(otherField);
+ }
+ bodyPart.setHeader(header);
+ }
+ final Body otherBody = otherPart.getBody();
+ if (otherBody != null) {
+ Body body = null;
+ if (otherBody instanceof Message) {
+ body = MessageBuilder.createCopy((Message) otherBody).build();
+ } else if (otherBody instanceof Multipart) {
+ body = MultipartBuilder.createCopy((Multipart) otherBody).build();
+ } else if (otherBody instanceof SingleBody) {
+ body = ((SingleBody) otherBody).copy();
+ }
+ bodyPart.setBody(body);
+ }
+ bodyParts.add(bodyPart);
+ }
+ preamble = other.getPreamble();
+ epilogue = other.getEpilogue();
+ return this;
+ }
+
public Multipart build() {
MultipartImpl multipart = new MultipartImpl(subType);
for (Entity part : bodyParts) {
diff --git a/dom/src/main/java/org/apache/james/mime4j/message/SingleBodyBuilder.java b/dom/src/main/java/org/apache/james/mime4j/message/SingleBodyBuilder.java
index 12a43b3..eed1a72 100644
--- a/dom/src/main/java/org/apache/james/mime4j/message/SingleBodyBuilder.java
+++ b/dom/src/main/java/org/apache/james/mime4j/message/SingleBodyBuilder.java
@@ -22,13 +22,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
import org.apache.james.mime4j.Charsets;
import org.apache.james.mime4j.dom.BinaryBody;
import org.apache.james.mime4j.dom.SingleBody;
import org.apache.james.mime4j.dom.TextBody;
import org.apache.james.mime4j.io.InputStreams;
+import org.apache.james.mime4j.util.CharsetUtil;
import org.apache.james.mime4j.util.ContentUtil;
/**
@@ -40,12 +44,16 @@
return new SingleBodyBuilder();
}
- private BodyFactory bodyFactory;
+ public static SingleBodyBuilder createCopy(final SingleBody other) throws IOException {
+ return new SingleBodyBuilder().copy(other);
+ }
private String text;
private byte[] bin;
private Charset charset;
+ private BodyFactory bodyFactory;
+
SingleBodyBuilder() {
super();
}
@@ -84,6 +92,26 @@
return this;
}
+ public SingleBodyBuilder copy(final SingleBody other) throws IOException {
+ if (other == null) {
+ return this;
+ }
+ if (other instanceof TextBody) {
+ String charsetName = ((TextBody) other).getMimeCharset();
+ if (charsetName != null) {
+ try {
+ this.charset = Charset.forName(charsetName);
+ } catch (IllegalCharsetNameException ex) {
+ throw new UnsupportedEncodingException(charsetName);
+ } catch (UnsupportedCharsetException ex) {
+ throw new UnsupportedEncodingException(charsetName);
+ }
+ }
+ }
+ this.bin = ContentUtil.buffer(other.getInputStream());
+ return this;
+ }
+
public TextBody buildText() throws IOException {
Charset cs = this.charset != null ? this.charset : Charsets.DEFAULT_CHARSET;
if (this.bodyFactory != null) {
diff --git a/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java b/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java
index 44b64d3..298074b 100644
--- a/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java
+++ b/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java
@@ -61,21 +61,23 @@
.generateMessageId(InetAddress.getLocalHost().getCanonicalHostName())
// 3) set a multipart body
.setBody(MultipartBuilder.create("mixed")
- // a multipart may have a preamble
+ .use(bodyFactory)
+ // a multipart may have a preamble
.setPreamble("This is a multi-part message in MIME format.")
- // first part is text/plain
+ // first part is text/plain
.addBodyPart(BodyPartBuilder.create()
.use(bodyFactory)
.setBody("Why so serious?", Charsets.UTF_8)
.setContentTransferEncoding("quoted-printable")
.build())
- // second part is image/png (image is created on the fly)
+ // second part is image/png (image is created on the fly)
.addBodyPart(BodyPartBuilder.create()
+ .use(bodyFactory)
.setBody(createImageBody(bodyFactory, renderSampleImage()))
.setContentType("image/png")
.setContentTransferEncoding("base64")
- // Specify a filename in the Content-Disposition header (implicitly sets
- // the disposition type to "attachment")
+ // Specify a filename in the Content-Disposition header (implicitly sets
+ // the disposition type to "attachment")
.setContentDisposition("attachment", "smiley.png")
.build())
.build())
diff --git a/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java b/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
index 607d121..996aeaf 100644
--- a/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
+++ b/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
@@ -19,26 +19,21 @@
package org.apache.james.mime4j.samples.transform;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Random;
-import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.Charsets;
+import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.dom.MessageBuilder;
import org.apache.james.mime4j.dom.MessageWriter;
import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.dom.TextBody;
-import org.apache.james.mime4j.dom.field.ParseException;
-import org.apache.james.mime4j.field.address.AddressBuilder;
import org.apache.james.mime4j.message.BodyPart;
-import org.apache.james.mime4j.message.MessageImpl;
-import org.apache.james.mime4j.message.DefaultMessageBuilder;
+import org.apache.james.mime4j.message.BodyPartBuilder;
import org.apache.james.mime4j.message.DefaultMessageWriter;
-import org.apache.james.mime4j.message.MultipartImpl;
-import org.apache.james.mime4j.storage.DefaultStorageProvider;
+import org.apache.james.mime4j.message.MessageBuilder;
+import org.apache.james.mime4j.message.MultipartBuilder;
import org.apache.james.mime4j.storage.StorageBodyFactory;
import org.apache.james.mime4j.storage.StorageProvider;
import org.apache.james.mime4j.storage.TempFileStorageProvider;
@@ -56,15 +51,68 @@
// Explicitly set a strategy for storing body parts. Usually not
// necessary; for most applications the default setting is appropriate.
StorageProvider storageProvider = new TempFileStorageProvider();
- DefaultStorageProvider.setInstance(storageProvider);
+ StorageBodyFactory bodyFactory = new StorageBodyFactory(storageProvider, DecodeMonitor.SILENT);
// Create a template message. It would be possible to load a message
// from an input stream but for this example a message object is created
// from scratch for demonstration purposes.
- Message template = createTemplate();
+ Message template = MessageBuilder.create()
+ .setBody(MultipartBuilder.create("mixed")
+ .addBodyPart(BodyPartBuilder.create()
+ .use(bodyFactory)
+ .setBody("This is the first part of the template..", Charsets.UTF_8)
+ .setContentTransferEncoding("quoted-printable")
+ .build())
+ .addBodyPart(BodyPartBuilder.create()
+ .use(bodyFactory)
+ .setBody(createRandomBinary(200), "application/octet-stream")
+ .setContentTransferEncoding("base64")
+ .build())
+ .addBodyPart(BodyPartBuilder.create()
+ .use(bodyFactory)
+ .setBody(createRandomBinary(300), "application/octet-stream")
+ .setContentTransferEncoding("base64")
+ .build())
+ .build())
+ .setSubject("Template message")
+ .build();
// Create a new message by transforming the template.
- Message transformed = transform(template);
+ // Create a copy of the template. The copy can be modified without
+ // affecting the original.
+ final MessageBuilder messageBuilder = MessageBuilder.createCopy(template);
+ // In this example we know we have a multipart message. Use
+ // Message#isMultipart() if uncertain.
+ Multipart multipart = (Multipart) messageBuilder.getBody();
+
+ // Insert a new text/plain body part after every body part of the
+ // template.
+ final int count = multipart.getCount();
+ for (int i = 0; i < count; i++) {
+ String text = "Text inserted after part " + (i + 1);
+ BodyPart bodyPart = BodyPartBuilder.create()
+ .use(bodyFactory)
+ .setBody(text, Charsets.UTF_8)
+ .setContentTransferEncoding("quoted-printable")
+ .build();
+ multipart.addBodyPart(bodyPart, 2 * i + 1);
+ }
+
+ // For no particular reason remove the second binary body part (now
+ // at index four).
+ Entity removed = multipart.removeBodyPart(4);
+
+ // The removed body part no longer has a parent entity it belongs to so
+ // it should be disposed of.
+ removed.dispose();
+
+ // Set some headers on the transformed message
+ messageBuilder.generateMessageId(HOSTNAME);
+ messageBuilder.setSubject("Transformed message");
+ messageBuilder.setDate(new Date());
+ messageBuilder.setFrom("John Doe <jdoe@machine.example>");
+
+ Message transformed = messageBuilder.build();
MessageWriter writer = new DefaultMessageWriter();
@@ -89,99 +137,11 @@
// messages and body parts have been disposed of properly.
}
- /**
- * Copies the given message and makes some arbitrary changes to the copy.
- * @throws ParseException on bad arguments
- */
- private static Message transform(Message original) throws IOException, ParseException {
- // Create a copy of the template. The copy can be modified without
- // affecting the original.
- MessageBuilder builder = new DefaultMessageBuilder();
- Message message = builder.newMessage(original);
-
- // In this example we know we have a multipart message. Use
- // Message#isMultipart() if uncertain.
- Multipart multipart = (Multipart) message.getBody();
-
- // Insert a new text/plain body part after every body part of the
- // template.
- final int count = multipart.getCount();
- for (int i = 0; i < count; i++) {
- String text = "Text inserted after part " + (i + 1);
- BodyPart bodyPart = createTextPart(text);
- multipart.addBodyPart(bodyPart, 2 * i + 1);
- }
-
- // For no particular reason remove the second binary body part (now
- // at index four).
- Entity removed = multipart.removeBodyPart(4);
-
- // The removed body part no longer has a parent entity it belongs to so
- // it should be disposed of.
- removed.dispose();
-
- // Set some headers on the transformed message
- message.createMessageId(HOSTNAME);
- message.setSubject("Transformed message");
- message.setDate(new Date());
- message.setFrom(AddressBuilder.DEFAULT.parseMailbox("John Doe <jdoe@machine.example>"));
-
- return message;
- }
-
- /**
- * Creates a multipart/mixed message that consists of three parts (one text,
- * two binary).
- */
- private static Message createTemplate() throws IOException {
- Multipart multipart = new MultipartImpl("mixed");
-
- BodyPart part1 = createTextPart("This is the first part of the template..");
- multipart.addBodyPart(part1);
-
- BodyPart part2 = createRandomBinaryPart(200);
- multipart.addBodyPart(part2);
-
- BodyPart part3 = createRandomBinaryPart(300);
- multipart.addBodyPart(part3);
-
- MessageImpl message = new MessageImpl();
- message.setMultipart(multipart);
-
- message.setSubject("Template message");
-
- return message;
- }
-
- /**
- * Creates a text part from the specified string.
- */
- private static BodyPart createTextPart(String text) {
- TextBody body = new StorageBodyFactory().textBody(text, "UTF-8");
-
- BodyPart bodyPart = new BodyPart();
- bodyPart.setText(body);
- bodyPart.setContentTransferEncoding("quoted-printable");
-
- return bodyPart;
- }
-
- /**
- * Creates a binary part with random content.
- */
- private static BodyPart createRandomBinaryPart(int numberOfBytes)
+ private static byte[] createRandomBinary(int numberOfBytes)
throws IOException {
byte[] data = new byte[numberOfBytes];
new Random().nextBytes(data);
-
- Body body = new StorageBodyFactory()
- .binaryBody(new ByteArrayInputStream(data));
-
- BodyPart bodyPart = new BodyPart();
- bodyPart.setBody(body, "application/octet-stream");
- bodyPart.setContentTransferEncoding("base64");
-
- return bodyPart;
+ return data;
}
}