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.BodyPart;
19 import com.android.voicemail.impl.mail.MessagingException;
20 import com.android.voicemail.impl.mail.Multipart;
21 import java.io.BufferedWriter;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.io.OutputStreamWriter;
26 
27 public class MimeMultipart extends Multipart {
28   protected String preamble;
29 
30   protected String contentType;
31 
32   protected String boundary;
33 
34   protected String subType;
35 
MimeMultipart()36   public MimeMultipart() throws MessagingException {
37     boundary = generateBoundary();
38     setSubType("mixed");
39   }
40 
MimeMultipart(String contentType)41   public MimeMultipart(String contentType) throws MessagingException {
42     this.contentType = contentType;
43     try {
44       subType = MimeUtility.getHeaderParameter(contentType, null).split("/")[1];
45       boundary = MimeUtility.getHeaderParameter(contentType, "boundary");
46       if (boundary == null) {
47         throw new MessagingException("MultiPart does not contain boundary: " + contentType);
48       }
49     } catch (Exception e) {
50       throw new MessagingException(
51           "Invalid MultiPart Content-Type; must contain subtype and boundary. ("
52               + contentType
53               + ")",
54           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 preamble;
69   }
70 
setPreamble(String preamble)71   public void setPreamble(String preamble) throws MessagingException {
72     this.preamble = preamble;
73   }
74 
75   @Override
getContentType()76   public String getContentType() throws MessagingException {
77     return contentType;
78   }
79 
setSubType(String subType)80   public void setSubType(String subType) throws MessagingException {
81     this.subType = subType;
82     contentType = String.format("multipart/%s; boundary=\"%s\"", subType, boundary);
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 (preamble != null) {
90       writer.write(preamble + "\r\n");
91     }
92 
93     for (int i = 0, count = parts.size(); i < count; i++) {
94       BodyPart bodyPart = parts.get(i);
95       writer.write("--" + boundary + "\r\n");
96       writer.flush();
97       bodyPart.writeTo(out);
98       writer.write("\r\n");
99     }
100 
101     writer.write("--" + boundary + "--\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 subType;
112   }
113 }
114