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