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