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 2014/06/29 13:40:02 UTC

svn commit: r1606455 - in /james/mime4j/trunk: dom/src/main/java/org/apache/james/mime4j/message/ examples/src/main/java/org/apache/james/mime4j/samples/dom/

Author: olegk
Date: Sun Jun 29 11:40:02 2014
New Revision: 1606455

URL: http://svn.apache.org/r1606455
Log:
Added builder class for BodyPart and Multipart instances

Added:
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java   (with props)
    james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java   (with props)
Modified:
    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

Added: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java?rev=1606455&view=auto
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java (added)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java Sun Jun 29 11:40:02 2014
@@ -0,0 +1,136 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mime4j.message;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Date;
+
+import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.dom.Header;
+import org.apache.james.mime4j.stream.Field;
+import org.apache.james.mime4j.stream.NameValuePair;
+
+/**
+ * {@link org.apache.james.mime4j.message.BodyPart} builder.
+ */
+public class BodyPartBuilder extends AbstractEntityBuilder {
+
+    public static BodyPartBuilder create() {
+        return new BodyPartBuilder();
+    }
+
+    @Override
+    public BodyPartBuilder setField(Field field) {
+        super.setField(field);
+        return this;
+    }
+
+    @Override
+    public AbstractEntityBuilder addField(Field field) {
+        super.addField(field);
+        return this;
+    }
+
+    @Override
+    public AbstractEntityBuilder removeFields(String name) {
+        super.removeFields(name);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setContentTransferEncoding(String contentTransferEncoding) {
+        super.setContentTransferEncoding(contentTransferEncoding);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setContentType(String mimeType, NameValuePair... parameters) {
+        super.setContentType(mimeType, parameters);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setContentDisposition(String dispositionType) {
+        super.setContentDisposition(dispositionType);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setContentDisposition(String dispositionType, String filename) {
+        super.setContentDisposition(dispositionType, filename);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setContentDisposition(String dispositionType, String filename, long size) {
+        super.setContentDisposition(dispositionType, filename, size);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setContentDisposition(String dispositionType,
+                                                 String filename,
+                                                 long size,
+                                                 Date creationDate,
+                                                 Date modificationDate,
+                                                 Date readDate) {
+        super.setContentDisposition(dispositionType, filename, size, creationDate, modificationDate, readDate);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setBody(Body body) {
+        super.setBody(body);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder use(final BodyFactory bodyFactory) {
+        super.use(bodyFactory);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setBody(String text, Charset charset) throws IOException {
+        super.setBody(text, charset);
+        return this;
+    }
+
+    @Override
+    public BodyPartBuilder setBody(String text, String subtype, Charset charset) throws IOException {
+        super.setBody(text, subtype, charset);
+        return this;
+    }
+
+    public BodyPart build() {
+        BodyPart bodyPart = new BodyPart();
+        HeaderImpl header = new HeaderImpl();
+        bodyPart.setHeader(header);
+        for (Field field : getFields()) {
+            header.addField(field);
+        }
+
+        bodyPart.setBody(getBody());
+
+        return bodyPart;
+    }
+
+}

Propchange: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BodyPartBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java?rev=1606455&view=auto
==============================================================================
--- james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java (added)
+++ james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java Sun Jun 29 11:40:02 2014
@@ -0,0 +1,207 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mime4j.message;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.mime4j.dom.Entity;
+import org.apache.james.mime4j.dom.Multipart;
+
+/**
+ * {@link org.apache.james.mime4j.dom.Multipart} builder.
+ */
+public class MultipartBuilder {
+
+    private final List<Entity> bodyParts;
+    private String subType;
+    private String preamble;
+    private String epilogue;
+
+    public static MultipartBuilder create(String subType) {
+        return new MultipartBuilder().setSubType(subType);
+    }
+
+    public static MultipartBuilder create() {
+        return new MultipartBuilder();
+    }
+
+    private MultipartBuilder() {
+        this.bodyParts = new LinkedList<Entity>();
+    }
+
+    /**
+     * 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 meaning.
+     *
+     * @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 MultipartBuilder setSubType(String subType) {
+        this.subType = subType;
+        return this;
+    }
+
+    /**
+     * Returns the number of body parts.
+     *
+     * @return number of <code>Entity</code> objects.
+     */
+    public int getCount() {
+        return bodyParts.size();
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * Adds a body part to the end of the list of body parts.
+     *
+     * @param bodyPart
+     *            the body part.
+     */
+    public MultipartBuilder addBodyPart(Entity bodyPart) {
+        if (bodyPart == null) {
+            throw new IllegalArgumentException();
+        }
+        bodyParts.add(bodyPart);
+        return this;
+    }
+
+    /**
+     * Inserts a body part at the specified position in the list of body parts.
+     *
+     * @param bodyPart
+     *            the body part.
+     * @param index
+     *            index at which the specified body part is to be inserted.
+     */
+    public MultipartBuilder addBodyPart(Entity bodyPart, int index) {
+        if (bodyPart == null) {
+            throw new IllegalArgumentException();
+        }
+        bodyParts.add(index, bodyPart);
+        return this;
+    }
+
+    /**
+     * Removes the body part at the specified position in the list of body
+     * parts.
+     *
+     * @param index
+     *            index of the body part to be removed.
+     * @return the removed body part.
+     */
+    public MultipartBuilder removeBodyPart(int index) {
+        bodyParts.remove(index);
+        return this;
+    }
+
+    /**
+     * Replaces the body part at the specified position in the list of body
+     * parts with the specified body part.
+     *
+     * @param bodyPart
+     *            body part to be stored at the specified position.
+     * @param index
+     *            index of body part to replace.
+     * @return the replaced body part.
+     * @throws IndexOutOfBoundsException
+     *             if the index is out of range (index &lt; 0 || index &gt;=
+     *             getCount()).
+     */
+    public MultipartBuilder replaceBodyPart(Entity bodyPart, int index) {
+        if (bodyPart == null) {
+            throw new IllegalArgumentException();
+        }
+        bodyParts.set(index, bodyPart);
+        return this;
+    }
+
+    /**
+     * Returns preamble.
+     *
+     * @return the preamble.
+     */
+    public String getPreamble() {
+        return preamble;
+    }
+
+    /**
+     * Sets the preamble.
+     *
+     * @param preamble
+     *            the preamble.
+     */
+    public MultipartBuilder setPreamble(String preamble) {
+        this.preamble = preamble;
+        return this;
+    }
+
+    /**
+     * Returns epilogue.
+     *
+     * @return the epilogue.
+     */
+    public String getEpilogue() {
+        return epilogue;
+    }
+
+    /**
+     * Sets the epilogue.
+     *
+     * @param epilogue
+     *            the epilogue.
+     */
+    public MultipartBuilder setEpilogue(String epilogue) {
+        this.epilogue = epilogue;
+        return this;
+    }
+
+    public Multipart build() {
+        MultipartImpl multipart = new MultipartImpl(subType);
+        for (Entity part : bodyParts) {
+            multipart.addBodyPart(part);
+        }
+        multipart.setPreamble(preamble);
+        multipart.setEpilogue(epilogue);
+        return multipart;
+    }
+
+}

Propchange: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/MultipartBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java?rev=1606455&r1=1606454&r2=1606455&view=diff
==============================================================================
--- james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java (original)
+++ james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/MultipartMessage.java Sun Jun 29 11:40:02 2014
@@ -19,25 +19,22 @@
 
 package org.apache.james.mime4j.samples.dom;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
+import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
+import java.net.InetAddress;
 import java.util.Date;
 
 import javax.imageio.ImageIO;
 
+import org.apache.james.mime4j.Charsets;
 import org.apache.james.mime4j.dom.BinaryBody;
+import org.apache.james.mime4j.dom.Message;
 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.field.address.AddressBuilder;
-import org.apache.james.mime4j.message.BodyPart;
-import org.apache.james.mime4j.message.MessageImpl;
+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.message.MessageBuilder;
+import org.apache.james.mime4j.message.MultipartBuilder;
 import org.apache.james.mime4j.storage.Storage;
 import org.apache.james.mime4j.storage.StorageBodyFactory;
 import org.apache.james.mime4j.storage.StorageOutputStream;
@@ -52,87 +49,57 @@ public class MultipartMessage {
 
     public static void main(String[] args) throws Exception {
         // 1) start with an empty message
-
-        MessageImpl message = new MessageImpl();
-
+        StorageBodyFactory bodyFactory = new StorageBodyFactory();
+        Message message = MessageBuilder.create()
         // 2) set header fields
-
-        // Date and From are required fields
-        message.setDate(new Date());
-        message.setFrom(AddressBuilder.DEFAULT.parseMailbox("John Doe <jd...@machine.example>"));
-
-        // Message-ID should be present
-        message.createMessageId("machine.example");
-
-        // set some optional fields
-        message.setTo(AddressBuilder.DEFAULT.parseMailbox("Mary Smith <ma...@example.net>"));
-        message.setSubject("An image for you");
-
+        //    Date and From are required fields
+        //    Message-ID should be present
+                .setFrom("John Doe <jd...@machine.example>")
+                .setTo("Mary Smith <ma...@example.net>")
+                .setSubject("An image for you")
+                .setDate(new Date())
+                .generateMessageId(InetAddress.getLocalHost().getCanonicalHostName())
         // 3) set a multipart body
-
-        Multipart multipart = new MultipartImpl("mixed");
-
-        // a multipart may have a preamble
-        multipart.setPreamble("This is a multi-part message in MIME format.");
-
-        // first part is text/plain
-        StorageBodyFactory bodyFactory = new StorageBodyFactory();
-        BodyPart textPart = createTextPart(bodyFactory, "Why so serious?");
-        multipart.addBodyPart(textPart);
-
-        // second part is image/png (image is created on the fly)
-        BufferedImage image = renderSampleImage();
-        BodyPart imagePart = createImagePart(bodyFactory, image);
-        multipart.addBodyPart(imagePart);
-
-        // setMultipart also sets the Content-Type header field
-        message.setMultipart(multipart);
-
+                .setBody(MultipartBuilder.create("mixed")
+                        // a multipart may have a preamble
+                        .setPreamble("This is a multi-part message in MIME format.")
+                        // 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)
+                        .addBodyPart(BodyPartBuilder.create()
+                                .setBody(createImageBody(bodyFactory, renderSampleImage()))
+                                .setContentType("image/png")
+                                .setContentTransferEncoding("base64")
+                        // Specify a filename in the Content-Disposition header (implicitly sets
+                        // the disposition type to "attachment")
+                                .setContentDisposition("attachment", "smiley.png")
+                                .build())
+                        .build())
+        // setBody also sets the Content-Type header field
+                .build();
+        try {
         // 4) print message to standard output
-
-        MessageWriter writer = new DefaultMessageWriter();
-        writer.writeMessage(message, System.out);
-
+            MessageWriter writer = new DefaultMessageWriter();
+            writer.writeMessage(message, System.out);
+        } finally {
         // 5) message is no longer needed and should be disposed of
-
-        message.dispose();
-    }
-
-    /**
-     * Creates a text part from the specified string.
-     */
-    private static BodyPart createTextPart(StorageBodyFactory bodyFactory, String text) {
-        // Use UTF-8 to encode the specified text
-        TextBody body = bodyFactory.textBody(text, "UTF-8");
-
-        // Create a text/plain body part
-        BodyPart bodyPart = new BodyPart();
-        bodyPart.setText(body);
-        bodyPart.setContentTransferEncoding("quoted-printable");
-
-        return bodyPart;
+            message.dispose();
+        }
     }
 
     /**
      * Creates a binary part from the specified image.
      */
-    private static BodyPart createImagePart(StorageBodyFactory bodyFactory,
+    private static BinaryBody createImageBody(StorageBodyFactory bodyFactory,
             BufferedImage image) throws IOException {
         // Create a binary message body from the image
         StorageProvider storageProvider = bodyFactory.getStorageProvider();
         Storage storage = storeImage(storageProvider, image, "png");
-        BinaryBody body = bodyFactory.binaryBody(storage);
-
-        // Create a body part with the correct MIME-type and transfer encoding
-        BodyPart bodyPart = new BodyPart();
-        bodyPart.setBody(body, "image/png");
-        bodyPart.setContentTransferEncoding("base64");
-
-        // Specify a filename in the Content-Disposition header (implicitly sets
-        // the disposition type to "attachment")
-        bodyPart.setFilename("smiley.png");
-
-        return bodyPart;
+        return bodyFactory.binaryBody(storage);
     }
 
     /**

Modified: james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/TextPlainMessage.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/TextPlainMessage.java?rev=1606455&r1=1606454&r2=1606455&view=diff
==============================================================================
--- james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/TextPlainMessage.java (original)
+++ james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/dom/TextPlainMessage.java Sun Jun 29 11:40:02 2014
@@ -35,7 +35,7 @@ import org.apache.james.mime4j.message.M
 public class TextPlainMessage {
     public static void main(String[] args) throws Exception {
         // 1) start with an empty message
-        final Message message = MessageBuilder.create()
+        Message message = MessageBuilder.create()
         // 2) set header fields
         //    Date and From are required fields
         //    Message-ID should be present