• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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;
18 
19 import com.android.email.mail.internet.BinaryTempFileBody;
20 import com.android.email.mail.internet.MimeBodyPart;
21 import com.android.email.mail.internet.MimeHeader;
22 import com.android.email.mail.internet.MimeMessage;
23 import com.android.email.mail.internet.MimeMultipart;
24 import com.android.email.mail.internet.TextBody;
25 import com.android.email.mail.store.LocalStore;
26 import com.android.email.provider.AttachmentProvider;
27 import com.android.email.provider.EmailContent;
28 
29 import android.net.Uri;
30 
31 import java.io.IOException;
32 import java.util.ArrayList;
33 
34 /**
35  * Utility class makes it easier for developer to build mail message objects.
36  * <p>
37  * Typical usage of these helper functions and builder objects are as follows.
38  * <p>
39  * <pre>
40  * String text2 = new TextBuilder("<html>").text("<head></head>")
41  *     .text("<body>").cidImg("contetid@domain").text("</body>").build("</html");
42  * String text2 = new TextBuilder("<html>").text("<head></head>")
43  *     .text("<body>").uriImg(contentUri).text("</body>").build("</html");
44  * Message msg = new MessageBuilder()
45  *     .setBody(new MultipartBuilder("multipart/mixed")
46  *         .addBodyPart(MessageTestUtils.imagePart("image/jpeg", null, 30, store))
47  *         .addBodyPart(MessageTestUtils.imagePart("application/pdf", cid1, aid1, store))
48  *         .addBodyPart(new MultipartBuilder("multipart/related")
49  *             .addBodyPart(MessageTestUtils.textPart("text/html", text2 + text1))
50  *             .addBodyPart(MessageTestUtils.imagePart("image/jpg", cid1, aid1, store))
51  *             .addBodyPart(MessageTestUtils.imagePart("image/gif", cid2, aid2, store))
52  *             .buildBodyPart())
53  *         .addBodyPart(MessageTestUtils.imagePart("application/pdf", cid2, aid2, store))
54  *         .build())
55  *     .build();
56  * </pre>
57  */
58 
59 public class MessageTestUtils {
60 
61     /**
62      * Generate AttachmentProvider content URI from attachment ID and Account.
63      *
64      * @param attachmentId attachment id
65      * @param account Account object
66      * @return AttachmentProvider content URI
67      */
contentUri(long attachmentId, EmailContent.Account account)68     public static Uri contentUri(long attachmentId, EmailContent.Account account) {
69         return AttachmentProvider.getAttachmentUri(account.mId, attachmentId);
70     }
71 
72     /**
73      * Create simple MimeBodyPart.
74      *
75      * @param mimeType MIME type of body part
76      * @param contentId content-id header value (optional - null for no header)
77      * @return MimeBodyPart object which body is null.
78      * @throws MessagingException
79      */
bodyPart(String mimeType, String contentId)80     public static BodyPart bodyPart(String mimeType, String contentId) throws MessagingException {
81         final MimeBodyPart bp = new MimeBodyPart(null, mimeType);
82         if (contentId != null) {
83             bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
84         }
85         return bp;
86     }
87 
88     /**
89      * Create MimeBodyPart with TextBody.
90      *
91      * @param mimeType MIME type of text
92      * @param text body text string
93      * @return MimeBodyPart object whose body is TextBody
94      * @throws MessagingException
95      */
textPart(String mimeType, String text)96     public static BodyPart textPart(String mimeType, String text) throws MessagingException {
97         final TextBody textBody = new TextBody(text);
98         final MimeBodyPart textPart = new MimeBodyPart(textBody);
99         textPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType);
100         return textPart;
101     }
102 
103     /**
104      * Create attachment BodyPart with content-id.
105      *
106      * @param mimeType MIME type of image body
107      * @param contentId content-id header value (optional - null for no header)
108      * @param attachmentId attachment id of store
109      * @param store LocalStore which stores attachment
110      * @return LocalAttachmentBodyPart with content-id
111      * @throws MessagingException
112      * @throws IOException
113      */
imagePart(String mimeType, String contentId, long attachmentId, LocalStore store)114     public static BodyPart imagePart(String mimeType, String contentId,
115             long attachmentId, LocalStore store) throws MessagingException, IOException {
116         final BinaryTempFileBody imageBody = new BinaryTempFileBody();
117         final LocalStore.LocalAttachmentBodyPart imagePart =
118             store.new LocalAttachmentBodyPart(imageBody, attachmentId);
119         imagePart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType);
120         if (contentId != null) {
121             imagePart.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
122         }
123         return imagePart;
124     }
125 
126     /**
127      * Builder class for Multipart.
128      *
129      * This builder object accepts any number of BodyParts and then can produce
130      * Multipart or BodyPart which contains accepted BodyParts. Usually combined with other
131      * builder object and helper method.
132      */
133     public static class MultipartBuilder {
134         private final String mContentType;
135         private final ArrayList<BodyPart> mParts = new ArrayList<BodyPart>();
136 
137         /**
138          * Create builder object with MIME type and dummy boundary string.
139          *
140          * @param mimeType MIME type of this Multipart
141          */
MultipartBuilder(String mimeType)142         public MultipartBuilder(String mimeType) {
143             this(mimeType, "this_is_boundary");
144         }
145 
146         /**
147          * Create builder object with MIME type and boundary string.
148          *
149          * @param mimeType MIME type of this Multipart
150          * @param boundary boundary string
151          */
MultipartBuilder(String mimeType, String boundary)152         public MultipartBuilder(String mimeType, String boundary) {
153             mContentType = mimeType + "; boundary=" + boundary;
154         }
155 
156         /**
157          * Modifier method to add BodyPart to intended Multipart.
158          *
159          * @param bodyPart BodyPart to be added
160          * @return builder object itself
161          */
addBodyPart(final BodyPart bodyPart)162         public MultipartBuilder addBodyPart(final BodyPart bodyPart) {
163             mParts.add(bodyPart);
164             return this;
165         }
166 
167         /**
168          * Build method to create Multipart.
169          *
170          * @return intended Multipart object
171          * @throws MessagingException
172          */
build()173         public Multipart build() throws MessagingException {
174             final MimeMultipart mp = new MimeMultipart(mContentType);
175             for (BodyPart p : mParts) {
176                 mp.addBodyPart(p);
177             }
178             return mp;
179         }
180 
181         /**
182          * Build method to create BodyPart that contains this "Multipart"
183          * @return BodyPart whose body is intended Multipart.
184          * @throws MessagingException
185          */
buildBodyPart()186         public BodyPart buildBodyPart() throws MessagingException {
187             final BodyPart bp = new MimeBodyPart();
188             bp.setBody(this.build());
189             return bp;
190         }
191     }
192 
193     /**
194      * Builder class for Message
195      *
196      * This builder object accepts Body and then can produce Message object.
197      * Usually combined with other builder object and helper method.
198      */
199     public static class MessageBuilder {
200         private Body mBody;
201 
202         /**
203          * Create Builder object.
204          */
MessageBuilder()205         public MessageBuilder() {
206         }
207 
208         /**
209          * Modifier method to set Body.
210          *
211          * @param body Body of intended Message
212          * @return builder object itself
213          */
setBody(final Body body)214         public MessageBuilder setBody(final Body body) {
215             mBody = body;
216             return this;
217         }
218 
219         /**
220          * Build method to create Message.
221          *
222          * @return intended Message object
223          * @throws MessagingException
224          */
build()225         public Message build() throws MessagingException {
226             final MimeMessage msg = new MimeMessage();
227             if (mBody == null) {
228                 throw new MessagingException("body is not specified");
229             }
230             msg.setBody(mBody);
231             return msg;
232         }
233     }
234 
235     /**
236      * Builder class for simple HTML String.
237      * This builder object accepts some type of object or and string and then create String object.
238      * Usually combined with other builder object and helper method.
239      */
240     public static class TextBuilder {
241         final StringBuilder mBuilder = new StringBuilder();
242 
243         /**
244          * Create builder with preamble string
245          * @param preamble
246          */
TextBuilder(String preamble)247         public TextBuilder(String preamble) {
248             mBuilder.append(preamble);
249         }
250 
251         /**
252          * Modifier method to add img tag that has cid: src attribute.
253          * @param contentId content id string
254          * @return builder object itself
255          */
addCidImg(String contentId)256         public TextBuilder addCidImg(String contentId) {
257             return addTag("img", "SRC", "cid:" + contentId);
258         }
259 
260         /**
261          * Modifier method to add img tag that has content:// src attribute.
262          * @param contentUri content uri object
263          * @return builder object itself
264          */
addUidImg(Uri contentUri)265         public TextBuilder addUidImg(Uri contentUri) {
266             return addTag("img", "src", contentUri.toString());
267         }
268 
269         /**
270          * Modifier method to add tag with specified attribute and value.
271          *
272          * @param tag tag name
273          * @param attribute attribute name
274          * @param value attribute value
275          * @return builder object itself
276          */
addTag(String tag, String attribute, String value)277         public TextBuilder addTag(String tag, String attribute, String value) {
278             return addText(String.format("<%s %s=\"%s\">", tag, attribute, value));
279         }
280 
281         /**
282          * Modifier method to add simple string.
283          * @param text string to add
284          * @return builder object itself
285          */
addText(String text)286         public TextBuilder addText(String text) {
287             mBuilder.append(text);
288             return this;
289         }
290 
291         /**
292          * Build method to create intended String
293          * @param epilogue string to add to the end
294          * @return intended String
295          */
build(String epilogue)296         public String build(String epilogue) {
297             mBuilder.append(epilogue);
298             return mBuilder.toString();
299         }
300     }
301 
302 }
303