Home | History | Annotate | Download | only in internet
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.emailcommon.internet;
     18 
     19 import com.android.emailcommon.mail.Body;
     20 import com.android.emailcommon.mail.BodyPart;
     21 import com.android.emailcommon.mail.MessagingException;
     22 
     23 import java.io.BufferedWriter;
     24 import java.io.IOException;
     25 import java.io.OutputStream;
     26 import java.io.OutputStreamWriter;
     27 import java.util.regex.Pattern;
     28 
     29 /**
     30  * TODO this is a close approximation of Message, need to update along with
     31  * Message.
     32  */
     33 public class MimeBodyPart extends BodyPart {
     34     protected MimeHeader mHeader = new MimeHeader();
     35     protected MimeHeader mExtendedHeader;
     36     protected Body mBody;
     37     protected int mSize;
     38 
     39     // regex that matches content id surrounded by "<>" optionally.
     40     private static final Pattern REMOVE_OPTIONAL_BRACKETS = Pattern.compile("^<?([^>]+)>?$");
     41     // regex that matches end of line.
     42     private static final Pattern END_OF_LINE = Pattern.compile("\r?\n");
     43 
     44     public MimeBodyPart() throws MessagingException {
     45         this(null);
     46     }
     47 
     48     public MimeBodyPart(Body body) throws MessagingException {
     49         this(body, null);
     50     }
     51 
     52     public MimeBodyPart(Body body, String mimeType) throws MessagingException {
     53         if (mimeType != null) {
     54             setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType);
     55         }
     56         setBody(body);
     57     }
     58 
     59     protected String getFirstHeader(String name) throws MessagingException {
     60         return mHeader.getFirstHeader(name);
     61     }
     62 
     63     @Override
     64     public void addHeader(String name, String value) throws MessagingException {
     65         mHeader.addHeader(name, value);
     66     }
     67 
     68     @Override
     69     public void setHeader(String name, String value) throws MessagingException {
     70         mHeader.setHeader(name, value);
     71     }
     72 
     73     @Override
     74     public String[] getHeader(String name) throws MessagingException {
     75         return mHeader.getHeader(name);
     76     }
     77 
     78     @Override
     79     public void removeHeader(String name) throws MessagingException {
     80         mHeader.removeHeader(name);
     81     }
     82 
     83     @Override
     84     public Body getBody() throws MessagingException {
     85         return mBody;
     86     }
     87 
     88     @Override
     89     public void setBody(Body body) throws MessagingException {
     90         this.mBody = body;
     91         if (body instanceof com.android.emailcommon.mail.Multipart) {
     92             com.android.emailcommon.mail.Multipart multipart =
     93                 ((com.android.emailcommon.mail.Multipart)body);
     94             multipart.setParent(this);
     95             setHeader(MimeHeader.HEADER_CONTENT_TYPE, multipart.getContentType());
     96         }
     97         else if (body instanceof TextBody) {
     98             String contentType = String.format("%s;\n charset=utf-8", getMimeType());
     99             String name = MimeUtility.getHeaderParameter(getContentType(), "name");
    100             if (name != null) {
    101                 contentType += String.format(";\n name=\"%s\"", name);
    102             }
    103             setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType);
    104             setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
    105         }
    106     }
    107 
    108     @Override
    109     public String getContentType() throws MessagingException {
    110         String contentType = getFirstHeader(MimeHeader.HEADER_CONTENT_TYPE);
    111         if (contentType == null) {
    112             return "text/plain";
    113         } else {
    114             return contentType;
    115         }
    116     }
    117 
    118     @Override
    119     public String getDisposition() throws MessagingException {
    120         String contentDisposition = getFirstHeader(MimeHeader.HEADER_CONTENT_DISPOSITION);
    121         if (contentDisposition == null) {
    122             return null;
    123         } else {
    124             return contentDisposition;
    125         }
    126     }
    127 
    128     @Override
    129     public String getContentId() throws MessagingException {
    130         String contentId = getFirstHeader(MimeHeader.HEADER_CONTENT_ID);
    131         if (contentId == null) {
    132             return null;
    133         } else {
    134             // remove optionally surrounding brackets.
    135             return REMOVE_OPTIONAL_BRACKETS.matcher(contentId).replaceAll("$1");
    136         }
    137     }
    138 
    139     @Override
    140     public String getMimeType() throws MessagingException {
    141         return MimeUtility.getHeaderParameter(getContentType(), null);
    142     }
    143 
    144     @Override
    145     public boolean isMimeType(String mimeType) throws MessagingException {
    146         return getMimeType().equals(mimeType);
    147     }
    148 
    149     public void setSize(int size) {
    150         this.mSize = size;
    151     }
    152 
    153     @Override
    154     public int getSize() throws MessagingException {
    155         return mSize;
    156     }
    157 
    158     /**
    159      * Set extended header
    160      *
    161      * @param name Extended header name
    162      * @param value header value - flattened by removing CR-NL if any
    163      * remove header if value is null
    164      * @throws MessagingException
    165      */
    166     @Override
    167     public void setExtendedHeader(String name, String value) throws MessagingException {
    168         if (value == null) {
    169             if (mExtendedHeader != null) {
    170                 mExtendedHeader.removeHeader(name);
    171             }
    172             return;
    173         }
    174         if (mExtendedHeader == null) {
    175             mExtendedHeader = new MimeHeader();
    176         }
    177         mExtendedHeader.setHeader(name, END_OF_LINE.matcher(value).replaceAll(""));
    178     }
    179 
    180     /**
    181      * Get extended header
    182      *
    183      * @param name Extended header name
    184      * @return header value - null if header does not exist
    185      * @throws MessagingException
    186      */
    187     @Override
    188     public String getExtendedHeader(String name) throws MessagingException {
    189         if (mExtendedHeader == null) {
    190             return null;
    191         }
    192         return mExtendedHeader.getFirstHeader(name);
    193     }
    194 
    195     /**
    196      * Write the MimeMessage out in MIME format.
    197      */
    198     @Override
    199     public void writeTo(OutputStream out) throws IOException, MessagingException {
    200         BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
    201         mHeader.writeTo(out);
    202         writer.write("\r\n");
    203         writer.flush();
    204         if (mBody != null) {
    205             mBody.writeTo(out);
    206         }
    207     }
    208 }
    209