• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.utility;
18 
19 import com.android.emailcommon.internet.MimeHeader;
20 import com.android.emailcommon.internet.MimeUtility;
21 import com.android.emailcommon.mail.MessagingException;
22 import com.android.emailcommon.mail.Part;
23 
24 import android.text.TextUtils;
25 
26 import java.util.ArrayList;
27 
28 public class ConversionUtilities {
29     /**
30      * Values for HEADER_ANDROID_BODY_QUOTED_PART to tag body parts
31      */
32     public static final String BODY_QUOTED_PART_REPLY = "quoted-reply";
33     public static final String BODY_QUOTED_PART_FORWARD = "quoted-forward";
34     public static final String BODY_QUOTED_PART_INTRO = "quoted-intro";
35 
36     /**
37      * Helper function to append text to a StringBuffer, creating it if necessary.
38      * Optimization:  The majority of the time we are *not* appending - we should have a path
39      * that deals with single strings.
40      */
appendTextPart(StringBuffer sb, String newText)41     private static StringBuffer appendTextPart(StringBuffer sb, String newText) {
42         if (newText == null) {
43             return sb;
44         }
45         else if (sb == null) {
46             sb = new StringBuffer(newText);
47         } else {
48             if (sb.length() > 0) {
49                 sb.append('\n');
50             }
51             sb.append(newText);
52         }
53         return sb;
54     }
55 
56     /**
57      * Plain-Old-Data class to return parsed body data from
58      * {@link ConversionUtilities#parseBodyFields}
59      */
60     public static class BodyFieldData {
61         public String textContent;
62         public String htmlContent;
63         public String textReply;
64         public String htmlReply;
65         public String introText;
66         public String snippet;
67         public boolean isQuotedReply;
68         public boolean isQuotedForward;
69     }
70 
71     /**
72      * Parse body text (plain and/or HTML) from MimeMessage to {@link BodyFieldData}.
73      */
parseBodyFields(ArrayList<Part> viewables)74     public static BodyFieldData parseBodyFields(ArrayList<Part> viewables)
75     throws MessagingException {
76         final BodyFieldData data = new BodyFieldData();
77         StringBuffer sbHtml = null;
78         StringBuffer sbText = null;
79         StringBuffer sbHtmlReply = null;
80         StringBuffer sbTextReply = null;
81         StringBuffer sbIntroText = null;
82 
83         for (Part viewable : viewables) {
84             String text = MimeUtility.getTextFromPart(viewable);
85             String[] replyTags = viewable.getHeader(MimeHeader.HEADER_ANDROID_BODY_QUOTED_PART);
86             String replyTag = null;
87             if (replyTags != null && replyTags.length > 0) {
88                 replyTag = replyTags[0];
89             }
90             // Deploy text as marked by the various tags
91             boolean isHtml = "text/html".equalsIgnoreCase(viewable.getMimeType());
92 
93             if (replyTag != null) {
94                 data.isQuotedReply = BODY_QUOTED_PART_REPLY.equalsIgnoreCase(replyTag);
95                 data.isQuotedForward = BODY_QUOTED_PART_FORWARD.equalsIgnoreCase(replyTag);
96                 boolean isQuotedIntro = BODY_QUOTED_PART_INTRO.equalsIgnoreCase(replyTag);
97 
98                 if (data.isQuotedReply || data.isQuotedForward) {
99                     if (isHtml) {
100                         sbHtmlReply = appendTextPart(sbHtmlReply, text);
101                     } else {
102                         sbTextReply = appendTextPart(sbTextReply, text);
103                     }
104                     continue;
105                 }
106                 if (isQuotedIntro) {
107                     sbIntroText = appendTextPart(sbIntroText, text);
108                     continue;
109                 }
110             }
111 
112             // Most of the time, just process regular body parts
113             if (isHtml) {
114                 sbHtml = appendTextPart(sbHtml, text);
115             } else {
116                 sbText = appendTextPart(sbText, text);
117             }
118         }
119 
120         // write the combined data to the body part
121         if (!TextUtils.isEmpty(sbText)) {
122             String text = sbText.toString();
123             data.textContent = text;
124             data.snippet = TextUtilities.makeSnippetFromPlainText(text);
125         }
126         if (!TextUtils.isEmpty(sbHtml)) {
127             String text = sbHtml.toString();
128             data.htmlContent = text;
129             if (data.snippet == null) {
130                 data.snippet = TextUtilities.makeSnippetFromHtmlText(text);
131             }
132         }
133         if (sbHtmlReply != null && sbHtmlReply.length() != 0) {
134             data.htmlReply = sbHtmlReply.toString();
135         }
136         if (sbTextReply != null && sbTextReply.length() != 0) {
137             data.textReply = sbTextReply.toString();
138         }
139         if (sbIntroText != null && sbIntroText.length() != 0) {
140             data.introText = sbIntroText.toString();
141         }
142         return data;
143     }
144 }
145