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.BodyPart;
20 import com.android.emailcommon.mail.MessagingException;
21 import com.android.emailcommon.mail.Multipart;
22 
23 import java.io.BufferedWriter;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 
29 public class MimeMultipart extends Multipart {
30     protected String mPreamble;
31 
32     protected String mContentType;
33 
34     protected String mBoundary;
35 
36     protected String mSubType;
37 
MimeMultipart()38     public MimeMultipart() throws MessagingException {
39         mBoundary = generateBoundary();
40         setSubType("mixed");
41     }
42 
MimeMultipart(String contentType)43     public MimeMultipart(String contentType) throws MessagingException {
44         this.mContentType = contentType;
45         try {
46             mSubType = MimeUtility.getHeaderParameter(contentType, null).split("/")[1];
47             mBoundary = MimeUtility.getHeaderParameter(contentType, "boundary");
48             if (mBoundary == null) {
49                 throw new MessagingException("MultiPart does not contain boundary: " + contentType);
50             }
51         } catch (Exception e) {
52             throw new MessagingException(
53                     "Invalid MultiPart Content-Type; must contain subtype and boundary. ("
54                             + contentType + ")", e);
55         }
56     }
57 
generateBoundary()58     public String generateBoundary() {
59         StringBuffer sb = new StringBuffer();
60         sb.append("----");
61         for (int i = 0; i < 30; i++) {
62             sb.append(Integer.toString((int)(Math.random() * 35), 36));
63         }
64         return sb.toString().toUpperCase();
65     }
66 
getPreamble()67     public String getPreamble() throws MessagingException {
68         return mPreamble;
69     }
70 
setPreamble(String preamble)71     public void setPreamble(String preamble) throws MessagingException {
72         this.mPreamble = preamble;
73     }
74 
75     @Override
getContentType()76     public String getContentType() throws MessagingException {
77         return mContentType;
78     }
79 
setSubType(String subType)80     public void setSubType(String subType) throws MessagingException {
81         this.mSubType = subType;
82         mContentType = String.format("multipart/%s; boundary=\"%s\"", subType, mBoundary);
83     }
84 
85     @Override
writeTo(OutputStream out)86     public void writeTo(OutputStream out) throws IOException, MessagingException {
87         BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
88 
89         if (mPreamble != null) {
90             writer.write(mPreamble + "\r\n");
91         }
92 
93         for (int i = 0, count = mParts.size(); i < count; i++) {
94             BodyPart bodyPart = mParts.get(i);
95             writer.write("--" + mBoundary + "\r\n");
96             writer.flush();
97             bodyPart.writeTo(out);
98             writer.write("\r\n");
99         }
100 
101         writer.write("--" + mBoundary + "--\r\n");
102         writer.flush();
103     }
104 
105     @Override
getInputStream()106     public InputStream getInputStream() throws MessagingException {
107         return null;
108     }
109 
getSubTypeForTest()110     public String getSubTypeForTest() {
111         return mSubType;
112     }
113 }
114