• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
63     @Override
addHeader(String name, String value)64     public void addHeader(String name, String value) throws MessagingException {
65         mHeader.addHeader(name, value);
66     }
67 
68     @Override
setHeader(String name, String value)69     public void setHeader(String name, String value) throws MessagingException {
70         mHeader.setHeader(name, value);
71     }
72 
73     @Override
getHeader(String name)74     public String[] getHeader(String name) throws MessagingException {
75         return mHeader.getHeader(name);
76     }
77 
78     @Override
removeHeader(String name)79     public void removeHeader(String name) throws MessagingException {
80         mHeader.removeHeader(name);
81     }
82 
83     @Override
getBody()84     public Body getBody() throws MessagingException {
85         return mBody;
86     }
87 
88     @Override
setBody(Body body)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
getContentType()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
getDisposition()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
getContentId()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
getMimeType()140     public String getMimeType() throws MessagingException {
141         return MimeUtility.getHeaderParameter(getContentType(), null);
142     }
143 
144     @Override
isMimeType(String mimeType)145     public boolean isMimeType(String mimeType) throws MessagingException {
146         return getMimeType().equals(mimeType);
147     }
148 
setSize(int size)149     public void setSize(int size) {
150         this.mSize = size;
151     }
152 
153     @Override
getSize()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
setExtendedHeader(String name, String value)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
getExtendedHeader(String name)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
writeTo(OutputStream out)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