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