@Test public void testMultipartDigestWithMessages() throws Exception { String data = "Content-Type: multipart/digest; boundary=\"bndry\"\r\n" + "\r\n" + "--bndry\r\n" + "\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "text body of first message\r\n" + "\r\n" + "--bndry\r\n" + "\r\n" + "Subject: subject of second message\r\n" + "Content-Type: multipart/alternative; boundary=\"bndry2\"\r\n" + "\r\n" + "--bndry2\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "text part of second message\r\n" + "\r\n" + "--bndry2\r\n" + "Content-Type: text/html\"\r\n" + "\r\n" + "html part of second message\r\n" + "\r\n" + "--bndry2--\r\n" + "\r\n" + "--bndry--\r\n"; MimeMessage message = MimeMessage.parseMimeMessage(new ByteArrayInputStream(data.getBytes()), false); List<Part> outputNonViewableParts = new ArrayList<>(); ArrayList<Viewable> outputViewableParts = new ArrayList<>(); List<ICalPart> outputCalendarParts = new ArrayList<>(); MessageExtractor.findViewablesAndAttachments(message, outputViewableParts, outputNonViewableParts, outputCalendarParts); String expectedExtractedText = "Subject: (No subject)\r\n" + "\r\n" + "text body of first message\r\n" + "\r\n" + "\r\n" + "------------------------------------------------------------------------\r\n" + "\r\n" + "Subject: subject of second message\r\n" + "\r\n" + "text part of second message\r\n"; String expectedHtmlText = "<table style=\"border: 0\">" + "<tr><th style=\"text-align: left; vertical-align: top;\">Subject:</th><td>(No subject)</td></tr>" + "</table>" + "<pre class=\"k9mail\">text body of first message<br /></pre>" + "<p style=\"margin-top: 2.5em; margin-bottom: 1em; border-bottom: 1px solid #000\"></p>" + "<table style=\"border: 0\">" + "<tr><th style=\"text-align: left; vertical-align: top;\">Subject:</th><td>subject of second message</td></tr>" + "</table>" + "<pre class=\"k9mail\">text part of second message<br /></pre>"; assertEquals(4, outputViewableParts.size()); assertEquals("subject of second message", ((MessageHeader) outputViewableParts.get(2)).getMessage().getSubject()); ViewableExtractedText firstMessageExtractedText = messageViewInfoExtractor.extractTextFromViewables(outputViewableParts); assertEquals(expectedExtractedText, firstMessageExtractedText.text); assertEquals(expectedHtmlText, firstMessageExtractedText.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);  }