@Test public void testTextPlusRfc822Message() throws MessagingException { K9ActivityCommon.setLanguage(context, "en"); Locale.setDefault(Locale.US); TimeZone.setDefault(TimeZone.getTimeZone("GMT+01:00")); String innerBodyText = "Hey there. I'm inside a message/rfc822 (inline) attachment."; TextBody textBody = new TextBody(BODY_TEXT); TextBody innerBody = new TextBody(innerBodyText); MimeMessage innerMessage = new MimeMessage(); innerMessage.addSentDate(new Date(112, 2, 17), false); innerMessage.setRecipients(RecipientType.TO, new Address[] { new Address("to@example.com") }); innerMessage.setSubject("Subject"); innerMessage.setFrom(new Address("from@example.com")); MimeMessageHelper.setBody(innerMessage, innerBody); MimeMultipart multipart = MimeMultipart.newInstance(); MimeBodyPart bodyPart1 = new MimeBodyPart(textBody, "text/plain"); MimeBodyPart bodyPart2 = new MimeBodyPart(innerMessage, "message/rfc822"); bodyPart2.setHeader("Content-Disposition", "inline; filename=\"message.eml\""); multipart.addBodyPart(bodyPart1); multipart.addBodyPart(bodyPart2); MimeMessage message = new MimeMessage(); MimeMessageHelper.setBody(message, multipart); List<Part> outputNonViewableParts = new ArrayList<Part>(); ArrayList<Viewable> outputViewableParts = new ArrayList<>(); MessageExtractor.findViewablesAndAttachments(message, outputViewableParts, outputNonViewableParts, null); ViewableExtractedText container = messageViewInfoExtractor.extractTextFromViewables(outputViewableParts); String expectedText = BODY_TEXT + "\r\n\r\n" + "----- message.eml ------------------------------------------------------" + "\r\n\r\n" + "From: from@example.com" + "\r\n" + "To: to@example.com" + "\r\n" + "Sent: Sat Mar 17 00:00:00 GMT+01:00 2012" + "\r\n" + "Subject: Subject" + "\r\n" + "\r\n" + innerBodyText; String expectedHtml = "<pre class=\"k9mail\">" + BODY_TEXT_HTML + "</pre>" + "<p style=\"margin-top: 2.5em; margin-bottom: 1em; border-bottom: " + "1px solid #000\">message.eml</p>" + "<table style=\"border: 0\">" + "<tr>" + "<th style=\"text-align: left; vertical-align: top;\">From:</th>" + "<td>from@example.com</td>" + "</tr><tr>" + "<th style=\"text-align: left; vertical-align: top;\">To:</th>" + "<td>to@example.com</td>" + "</tr><tr>" + "<th style=\"text-align: left; vertical-align: top;\">Sent:</th>" + "<td>Sat Mar 17 00:00:00 GMT+01:00 2012</td>" + "</tr><tr>" + "<th style=\"text-align: left; vertical-align: top;\">Subject:</th>" + "<td>Subject</td>" + "</tr>" + "</table>" + "<pre class=\"k9mail\">" + innerBodyText + "</pre>"; assertEquals(expectedText, container.text); assertEquals(expectedHtml, container.html); }
@VisibleForTesting ViewableExtractedText extractTextFromViewables(List<Viewable> viewables) throws MessagingException { try { boolean hideDivider = true; StringBuilder text = new StringBuilder(); StringBuilder html = new StringBuilder(); for (Viewable viewable : viewables) { if (viewable instanceof Textual) { text.append(buildText(viewable, !hideDivider)); html.append(buildHtml(viewable, !hideDivider)); hideDivider = false; } else if (viewable instanceof MessageHeader) { MessageHeader header = (MessageHeader) viewable; Part containerPart = header.getContainerPart(); Message innerMessage = header.getMessage(); addTextDivider(text, containerPart, !hideDivider); addMessageHeaderText(text, innerMessage); addHtmlDivider(html, containerPart, !hideDivider); addMessageHeaderHtml(html, innerMessage); hideDivider = true; } else if (viewable instanceof Alternative) { Alternative alternative = (Alternative) viewable; List<Viewable> textAlternative = alternative.getText().isEmpty() ? alternative.getHtml() : alternative.getText(); List<Viewable> htmlAlternative = alternative.getHtml().isEmpty() ? alternative.getText() : alternative.getHtml(); boolean divider = !hideDivider; for (Viewable textViewable : textAlternative) { text.append(buildText(textViewable, divider)); divider = true; } divider = !hideDivider; for (Viewable htmlViewable : htmlAlternative) { html.append(buildHtml(htmlViewable, divider)); divider = true; } hideDivider = false; } } String sanitizedHtml = htmlProcessor.processForDisplay(html.toString()); return new ViewableExtractedText(text.toString(), sanitizedHtml); } catch (Exception e) { throw new MessagingException("Couldn't extract viewable parts", e); } }
MessageViewInfoExtractor { @VisibleForTesting ViewableExtractedText extractTextFromViewables(List<Viewable> viewables) throws MessagingException { try { boolean hideDivider = true; StringBuilder text = new StringBuilder(); StringBuilder html = new StringBuilder(); for (Viewable viewable : viewables) { if (viewable instanceof Textual) { text.append(buildText(viewable, !hideDivider)); html.append(buildHtml(viewable, !hideDivider)); hideDivider = false; } else if (viewable instanceof MessageHeader) { MessageHeader header = (MessageHeader) viewable; Part containerPart = header.getContainerPart(); Message innerMessage = header.getMessage(); addTextDivider(text, containerPart, !hideDivider); addMessageHeaderText(text, innerMessage); addHtmlDivider(html, containerPart, !hideDivider); addMessageHeaderHtml(html, innerMessage); hideDivider = true; } else if (viewable instanceof Alternative) { Alternative alternative = (Alternative) viewable; List<Viewable> textAlternative = alternative.getText().isEmpty() ? alternative.getHtml() : alternative.getText(); List<Viewable> htmlAlternative = alternative.getHtml().isEmpty() ? alternative.getText() : alternative.getHtml(); boolean divider = !hideDivider; for (Viewable textViewable : textAlternative) { text.append(buildText(textViewable, divider)); divider = true; } divider = !hideDivider; for (Viewable htmlViewable : htmlAlternative) { html.append(buildHtml(htmlViewable, divider)); divider = true; } hideDivider = false; } } String sanitizedHtml = htmlProcessor.processForDisplay(html.toString()); return new ViewableExtractedText(text.toString(), sanitizedHtml); } catch (Exception e) { throw new MessagingException("Couldn't extract viewable parts", e); } } }
MessageViewInfoExtractor { @VisibleForTesting ViewableExtractedText extractTextFromViewables(List<Viewable> viewables) throws MessagingException { try { boolean hideDivider = true; StringBuilder text = new StringBuilder(); StringBuilder html = new StringBuilder(); for (Viewable viewable : viewables) { if (viewable instanceof Textual) { text.append(buildText(viewable, !hideDivider)); html.append(buildHtml(viewable, !hideDivider)); hideDivider = false; } else if (viewable instanceof MessageHeader) { MessageHeader header = (MessageHeader) viewable; Part containerPart = header.getContainerPart(); Message innerMessage = header.getMessage(); addTextDivider(text, containerPart, !hideDivider); addMessageHeaderText(text, innerMessage); addHtmlDivider(html, containerPart, !hideDivider); addMessageHeaderHtml(html, innerMessage); hideDivider = true; } else if (viewable instanceof Alternative) { Alternative alternative = (Alternative) viewable; List<Viewable> textAlternative = alternative.getText().isEmpty() ? alternative.getHtml() : alternative.getText(); List<Viewable> htmlAlternative = alternative.getHtml().isEmpty() ? alternative.getText() : alternative.getHtml(); boolean divider = !hideDivider; for (Viewable textViewable : textAlternative) { text.append(buildText(textViewable, divider)); divider = true; } divider = !hideDivider; for (Viewable htmlViewable : htmlAlternative) { html.append(buildHtml(htmlViewable, divider)); divider = true; } hideDivider = false; } } String sanitizedHtml = htmlProcessor.processForDisplay(html.toString()); return new ViewableExtractedText(text.toString(), sanitizedHtml); } catch (Exception e) { throw new MessagingException("Couldn't extract viewable parts", e); } } @VisibleForTesting  MessageViewInfoExtractor(Context context, AttachmentInfoExtractor attachmentInfoExtractor,
            ICalendarInfoExtractor iCalendarInfoExtractor, HtmlProcessor htmlProcessor); }
MessageViewInfoExtractor { @VisibleForTesting ViewableExtractedText extractTextFromViewables(List<Viewable> viewables) throws MessagingException { try { boolean hideDivider = true; StringBuilder text = new StringBuilder(); StringBuilder html = new StringBuilder(); for (Viewable viewable : viewables) { if (viewable instanceof Textual) { text.append(buildText(viewable, !hideDivider)); html.append(buildHtml(viewable, !hideDivider)); hideDivider = false; } else if (viewable instanceof MessageHeader) { MessageHeader header = (MessageHeader) viewable; Part containerPart = header.getContainerPart(); Message innerMessage = header.getMessage(); addTextDivider(text, containerPart, !hideDivider); addMessageHeaderText(text, innerMessage); addHtmlDivider(html, containerPart, !hideDivider); addMessageHeaderHtml(html, innerMessage); hideDivider = true; } else if (viewable instanceof Alternative) { Alternative alternative = (Alternative) viewable; List<Viewable> textAlternative = alternative.getText().isEmpty() ? alternative.getHtml() : alternative.getText(); List<Viewable> htmlAlternative = alternative.getHtml().isEmpty() ? alternative.getText() : alternative.getHtml(); boolean divider = !hideDivider; for (Viewable textViewable : textAlternative) { text.append(buildText(textViewable, divider)); divider = true; } divider = !hideDivider; for (Viewable htmlViewable : htmlAlternative) { html.append(buildHtml(htmlViewable, divider)); divider = true; } hideDivider = false; } } String sanitizedHtml = htmlProcessor.processForDisplay(html.toString()); return new ViewableExtractedText(text.toString(), sanitizedHtml); } catch (Exception e) { throw new MessagingException("Couldn't extract viewable parts", e); } } @VisibleForTesting  MessageViewInfoExtractor(Context context, AttachmentInfoExtractor attachmentInfoExtractor,
            ICalendarInfoExtractor iCalendarInfoExtractor, HtmlProcessor htmlProcessor); static MessageViewInfoExtractor getInstance(); @WorkerThread MessageViewInfo extractMessageForView(Message message, @Nullable MessageCryptoAnnotations cryptoAnnotations); }
MessageViewInfoExtractor { @VisibleForTesting ViewableExtractedText extractTextFromViewables(List<Viewable> viewables) throws MessagingException { try { boolean hideDivider = true; StringBuilder text = new StringBuilder(); StringBuilder html = new StringBuilder(); for (Viewable viewable : viewables) { if (viewable instanceof Textual) { text.append(buildText(viewable, !hideDivider)); html.append(buildHtml(viewable, !hideDivider)); hideDivider = false; } else if (viewable instanceof MessageHeader) { MessageHeader header = (MessageHeader) viewable; Part containerPart = header.getContainerPart(); Message innerMessage = header.getMessage(); addTextDivider(text, containerPart, !hideDivider); addMessageHeaderText(text, innerMessage); addHtmlDivider(html, containerPart, !hideDivider); addMessageHeaderHtml(html, innerMessage); hideDivider = true; } else if (viewable instanceof Alternative) { Alternative alternative = (Alternative) viewable; List<Viewable> textAlternative = alternative.getText().isEmpty() ? alternative.getHtml() : alternative.getText(); List<Viewable> htmlAlternative = alternative.getHtml().isEmpty() ? alternative.getText() : alternative.getHtml(); boolean divider = !hideDivider; for (Viewable textViewable : textAlternative) { text.append(buildText(textViewable, divider)); divider = true; } divider = !hideDivider; for (Viewable htmlViewable : htmlAlternative) { html.append(buildHtml(htmlViewable, divider)); divider = true; } hideDivider = false; } } String sanitizedHtml = htmlProcessor.processForDisplay(html.toString()); return new ViewableExtractedText(text.toString(), sanitizedHtml); } catch (Exception e) { throw new MessagingException("Couldn't extract viewable parts", e); } } @VisibleForTesting  MessageViewInfoExtractor(Context context, AttachmentInfoExtractor attachmentInfoExtractor,
            ICalendarInfoExtractor iCalendarInfoExtractor, HtmlProcessor htmlProcessor); static MessageViewInfoExtractor getInstance(); @WorkerThread MessageViewInfo extractMessageForView(Message message, @Nullable MessageCryptoAnnotations cryptoAnnotations);  }