Home | History | Annotate | Download | only in message
      1 /****************************************************************
      2  * Licensed to the Apache Software Foundation (ASF) under one   *
      3  * or more contributor license agreements.  See the NOTICE file *
      4  * distributed with this work for additional information        *
      5  * regarding copyright ownership.  The ASF licenses this file   *
      6  * to you under the Apache License, Version 2.0 (the            *
      7  * "License"); you may not use this file except in compliance   *
      8  * with the License.  You may obtain a copy of the License at   *
      9  *                                                              *
     10  *   http://www.apache.org/licenses/LICENSE-2.0                 *
     11  *                                                              *
     12  * Unless required by applicable law or agreed to in writing,   *
     13  * software distributed under the License is distributed on an  *
     14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
     15  * KIND, either express or implied.  See the License for the    *
     16  * specific language governing permissions and limitations      *
     17  * under the License.                                           *
     18  ****************************************************************/
     19 
     20 package org.apache.james.mime4j.message;
     21 
     22 import java.io.BufferedWriter;
     23 import java.io.IOException;
     24 import java.io.OutputStream;
     25 import java.io.OutputStreamWriter;
     26 import java.util.Collections;
     27 import java.util.Iterator;
     28 import java.util.LinkedList;
     29 import java.util.List;
     30 
     31 import org.apache.james.mime4j.field.ContentTypeField;
     32 import org.apache.james.mime4j.field.Field;
     33 import org.apache.james.mime4j.util.CharsetUtil;
     34 
     35 /**
     36  * Represents a MIME multipart body (see RFC 2045).A multipart body has a
     37  * ordered list of body parts. The multipart body also has a preamble and
     38  * epilogue. The preamble consists of whatever characters appear before the
     39  * first body part while the epilogue consists of whatever characters come
     40  * after the last body part.
     41  *
     42  *
     43  * @version $Id: Multipart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
     44  */
     45 public class Multipart implements Body {
     46     private String preamble = "";
     47     private String epilogue = "";
     48     private List bodyParts = new LinkedList();
     49     private Entity parent = null;
     50     private String subType = "alternative";
     51 
     52     /**
     53      * Creates a new empty <code>Multipart</code> instance.
     54      */
     55     public Multipart() {
     56     }
     57 
     58     /**
     59      * Gets the multipart sub-type. E.g. <code>alternative</code> (the default)
     60      * or <code>parallel</code>. See RFC 2045 for common sub-types and their
     61      * meaning.
     62      *
     63      * @return the multipart sub-type.
     64      */
     65     public String getSubType() {
     66         return subType;
     67     }
     68 
     69     /**
     70      * Sets the multipart sub-type. E.g. <code>alternative</code>
     71      * or <code>parallel</code>. See RFC 2045 for common sub-types and their
     72      * meaning.
     73      *
     74      * @param subType the sub-type.
     75      */
     76     public void setSubType(String subType) {
     77         this.subType = subType;
     78     }
     79 
     80     /**
     81      * @see org.apache.james.mime4j.message.Body#getParent()
     82      */
     83     public Entity getParent() {
     84         return parent;
     85     }
     86 
     87     /**
     88      * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
     89      */
     90     public void setParent(Entity parent) {
     91         this.parent = parent;
     92         for (Iterator it = bodyParts.iterator(); it.hasNext();) {
     93             ((BodyPart) it.next()).setParent(parent);
     94         }
     95     }
     96 
     97     /**
     98      * Gets the epilogue.
     99      *
    100      * @return the epilogue.
    101      */
    102     public String getEpilogue() {
    103         return epilogue;
    104     }
    105 
    106     /**
    107      * Sets the epilogue.
    108      *
    109      * @param epilogue the epilogue.
    110      */
    111     public void setEpilogue(String epilogue) {
    112         this.epilogue = epilogue;
    113     }
    114 
    115     /**
    116      * Gets the list of body parts. The list is immutable.
    117      *
    118      * @return the list of <code>BodyPart</code> objects.
    119      */
    120     public List getBodyParts() {
    121         return Collections.unmodifiableList(bodyParts);
    122     }
    123 
    124     /**
    125      * Sets the list of body parts.
    126      *
    127      * @param bodyParts the new list of <code>BodyPart</code> objects.
    128      */
    129     public void setBodyParts(List bodyParts) {
    130         this.bodyParts = bodyParts;
    131         for (Iterator it = bodyParts.iterator(); it.hasNext();) {
    132             ((BodyPart) it.next()).setParent(parent);
    133         }
    134     }
    135 
    136     /**
    137      * Adds a body part to the end of the list of body parts.
    138      *
    139      * @param bodyPart the body part.
    140      */
    141     public void addBodyPart(BodyPart bodyPart) {
    142         bodyParts.add(bodyPart);
    143         bodyPart.setParent(parent);
    144     }
    145 
    146     /**
    147      * Gets the preamble.
    148      *
    149      * @return the preamble.
    150      */
    151     public String getPreamble() {
    152         return preamble;
    153     }
    154 
    155     /**
    156      * Sets the preamble.
    157      *
    158      * @param preamble the preamble.
    159      */
    160     public void setPreamble(String preamble) {
    161         this.preamble = preamble;
    162     }
    163 
    164     /**
    165      *
    166      * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
    167      */
    168     public void writeTo(OutputStream out) throws IOException {
    169         String boundary = getBoundary();
    170         List bodyParts = getBodyParts();
    171 
    172         BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(getCharset())),8192);
    173 
    174         writer.write(getPreamble() + "\r\n");
    175 
    176         for (int i = 0; i < bodyParts.size(); i++) {
    177             writer.write(boundary + "\r\n");
    178             ((BodyPart) bodyParts.get(i)).writeTo(out);
    179         }
    180 
    181         writer.write(getEpilogue() + "\r\n");
    182         writer.write(boundary + "--" + "\r\n");
    183 
    184     }
    185 
    186     /**
    187      * Return the boundory of the parent Entity
    188      *
    189      * @return boundery
    190      */
    191     private String getBoundary() {
    192         Entity e = getParent();
    193         ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
    194                 Field.CONTENT_TYPE);
    195         return cField.getBoundary();
    196     }
    197 
    198     private String getCharset() {
    199         Entity e = getParent();
    200         String charString = ((ContentTypeField) e.getHeader().getField(Field.CONTENT_TYPE)).getCharset();
    201         return charString;
    202     }
    203 }
    204