Example usage for javax.mail Multipart getBodyPart

List of usage examples for javax.mail Multipart getBodyPart

Introduction

In this page you can find the example usage for javax.mail Multipart getBodyPart.

Prototype

public synchronized BodyPart getBodyPart(int index) throws MessagingException 

Source Link

Document

Get the specified Part.

Usage

From source file:com.cisco.iwe.services.util.EmailMonitor.java

/**
 * This method returns the corresponding JSON response.'Success = true' in case the Mail contents get stored in the database successfully. 'Success = false' in case of any errors 
 **///  w ww .  j ava2 s.  co m

public String monitorEmailAndLoadDB() {
    License license = new License();
    license.setLicense(EmailParseConstants.ocrLicenseFile);
    Store emailStore = null;
    Folder folder = null;
    Properties props = new Properties();
    logger.info("EmailMonitor monitorEmailAndLoadDB Enter (+)");
    // Setting session and Store information
    // MailServerConnectivity - get the email credentials based on the environment
    String[] mailCredens = getEmailCredens();
    final String username = mailCredens[0];
    final String password = mailCredens[1];
    logger.info("monitorEmailAndLoadDB : Email ID : " + username);

    try {
        logger.info("EmailMonitor.monitorEmailAndLoadDB get the mail server properties");
        props.put(EmailParseConstants.emailAuthKey, "true");
        props.put(EmailParseConstants.emailHostKey, prop.getProperty(EmailParseConstants.emailHost));
        props.put(EmailParseConstants.emailPortKey, prop.getProperty(EmailParseConstants.emailPort));
        props.put(EmailParseConstants.emailTlsKey, "true");

        logger.info("EmailMonitor.monitorEmailAndLoadDB create the session object with mail server properties");
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        // Prod-MailServerConnectivity - create the POP3 store object and
        // connect with the pop server
        logger.info("monitorEmailAndLoadDB : create the POP3 store object");
        emailStore = (Store) session.getStore(prop.getProperty(EmailParseConstants.emailType));
        logger.info("monitorEmailAndLoadDB : Connecting to Store :" + emailStore.toString());
        emailStore.connect(prop.getProperty(EmailParseConstants.emailHost),
                Integer.parseInt(prop.getProperty(EmailParseConstants.emailPort)), username, password);
        logger.info("monitorEmailAndLoadDB : Connection Status:" + emailStore.isConnected());

        // create the folder object
        folder = emailStore.getFolder(prop.getProperty(EmailParseConstants.emailFolder));
        // Check if Inbox exists
        if (!folder.exists()) {
            logger.error("monitorEmailAndLoadDB : No INBOX exists...");
            System.exit(0);
        }
        // Open inbox and read messages
        logger.info("monitorEmailAndLoadDB : Connected to Folder");
        folder.open(Folder.READ_WRITE);

        // retrieve the messages from the folder in an array and process it
        Message[] msgArr = folder.getMessages();
        // Read each message and delete the same once data is stored in DB
        logger.info("monitorEmailAndLoadDB : Message length::::" + msgArr.length);

        SimpleDateFormat sdf2 = new SimpleDateFormat(EmailParseConstants.dateFormat);

        Date sent = null;
        String emailContent = null;
        String contentType = null;
        // for (int i = 0; i < msg.length; i++) {
        for (int i = msgArr.length - 1; i > msgArr.length - 2; i--) {
            Message message = msgArr[i];
            if (!message.isSet(Flags.Flag.SEEN)) {
                try {
                    sent = msgArr[i].getSentDate();
                    contentType = message.getContentType();
                    String fileType = null;
                    byte[] byteArr = null;
                    String validAttachments = EmailParseConstants.validAttachmentTypes;
                    if (contentType.contains("multipart")) {
                        Multipart multiPart = (Multipart) message.getContent();
                        int numberOfParts = multiPart.getCount();
                        for (int partCount = 0; partCount < numberOfParts; partCount++) {
                            MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
                            InputStream inStream = (InputStream) part.getInputStream();
                            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                            int nRead;
                            byte[] data = new byte[16384];
                            while ((nRead = inStream.read(data, 0, data.length)) != -1) {
                                buffer.write(data, 0, nRead);
                            }
                            buffer.flush();
                            byteArr = buffer.toByteArray();
                            if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
                                fileType = part.getFileName().substring(part.getFileName().lastIndexOf("."),
                                        part.getFileName().length());
                                String fileDir = part.getFileName();
                                if (validAttachments.contains(fileType)) {
                                    part.saveFile(fileDir);
                                    saveAttachmentAndText(message.getFrom()[0].toString(), message.getSubject(),
                                            byteArr, emailContent.getBytes(), fileType, sent,
                                            fileType.equalsIgnoreCase(".PDF") ? scanPDF(fileDir)
                                                    : scanImage(fileDir).toString());
                                    deleteFile(fileDir);
                                } else {
                                    sendNotification();
                                }

                            } else {
                                // this part may be the message content
                                emailContent = part.getContent().toString();
                            }
                        }
                    } else if (contentType.contains("text/plain") || contentType.contains("text/html")) {
                        Object content = message.getContent();
                        if (content != null) {
                            emailContent = content.toString();
                        }
                    }
                    message.setFlag(Flags.Flag.DELETED, false);
                    logger.info(
                            "monitorEmailAndLoadDB : loadSuccess : Mail Parsed for : " + message.getSubject());
                    logger.info("monitorEmailAndLoadDB : loadSuccess : Created at : " + sdf2.format(sent));
                    logger.info("Message deleted");
                } catch (IOException e) {
                    logger.error("IO Exception in email monitoring: " + e);
                    logger.error(
                            "IO Exception in email monitoring message: " + Arrays.toString(e.getStackTrace()));
                } catch (SQLException sexp) {
                    logger.error("SQLException Occurred GetSpogDetails-db2 :", sexp);
                    buildErrorJson(ExceptionConstants.sqlErrCode, ExceptionConstants.sqlErrMsg);
                } catch (Exception e) {
                    logger.error("Unknown Exception in email monitoring: " + e);
                    logger.error("Unknown Exception in email monitoring message: "
                            + Arrays.toString(e.getStackTrace()));
                }
            }
        }

        // Close folder and store
        folder.close(true);
        emailStore.close();

    } catch (NoSuchProviderException e) {
        logger.error("monitorEmailAndLoadDB : NoSuchProviderException in email monitoring: " + e);
        logger.error("monitorEmailAndLoadDB : NoSuchProviderException in email monitoring message: "
                + Arrays.toString(e.getStackTrace()));
    } catch (MessagingException e) {
        logger.error("monitorEmailAndLoadDB : MessagingException in email monitoring: " + e);
        logger.error("monitorEmailAndLoadDB : MessagingException in email monitoring message: "
                + Arrays.toString(e.getStackTrace()));
    } finally {
        if (folder != null && folder.isOpen()) {
            // Close folder and store
            try {
                folder.close(true);
                emailStore.close();
            } catch (MessagingException e) {
                logger.error("monitorEmailAndLoadDB : MessagingException in email monitoring: " + e);
                logger.error("monitorEmailAndLoadDB : MessagingException in email monitoring: "
                        + Arrays.toString(e.getStackTrace()));
            }
        }
    }
    logger.info("EmailMonitor monitorEmailAndLoadDB Exit (-)");
    return buildSuccessJson().toString();
}

From source file:org.apache.camel.component.mail.MailBinding.java

protected void extractAttachmentsFromMultipart(Multipart mp, Map<String, DataHandler> map)
        throws javax.mail.MessagingException, IOException {

    for (int i = 0; i < mp.getCount(); i++) {
        Part part = mp.getBodyPart(i);
        LOG.trace("Part #" + i + ": " + part);

        if (part.isMimeType("multipart/*")) {
            LOG.trace("Part #" + i + ": is mimetype: multipart/*");
            extractAttachmentsFromMultipart((Multipart) part.getContent(), map);
        } else {/*from  ww w .  j  a  v a  2  s .c om*/
            String disposition = part.getDisposition();
            if (LOG.isTraceEnabled()) {
                LOG.trace("Part #" + i + ": Disposition: " + part.getDisposition());
                LOG.trace("Part #" + i + ": Description: " + part.getDescription());
                LOG.trace("Part #" + i + ": ContentType: " + part.getContentType());
                LOG.trace("Part #" + i + ": FileName: " + part.getFileName());
                LOG.trace("Part #" + i + ": Size: " + part.getSize());
                LOG.trace("Part #" + i + ": LineCount: " + part.getLineCount());
            }

            if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT)
                    || disposition.equalsIgnoreCase(Part.INLINE))) {
                // only add named attachments
                String fileName = part.getFileName();
                if (fileName != null) {
                    LOG.debug("Mail contains file attachment: " + fileName);
                    // Parts marked with a disposition of Part.ATTACHMENT are clearly attachments
                    CollectionHelper.appendValue(map, fileName, part.getDataHandler());
                }
            }
        }
    }
}

From source file:com.naryx.tagfusion.cfm.mail.cfPOP3.java

private void retrieveBody(cfSession _Session, Part Mess, cfQueryResultData popData, int Row, File attachmentDir)
        throws Exception {

    if (Mess.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) Mess.getContent();
        int count = mp.getCount();
        for (int i = 0; i < count; i++)
            retrieveBody(_Session, mp.getBodyPart(i), popData, Row, attachmentDir);

    } else {//  www  .  jav a  2  s.co  m
        String filename = cfMailMessageData.getFilename(Mess);
        String dispos = Mess.getDisposition();

        // note: text/enriched shouldn't be treated as a text part of the email (see bug #2227)
        if ((dispos == null || dispos.equalsIgnoreCase(Part.INLINE)) && Mess.isMimeType("text/*")
                && !Mess.isMimeType("text/enriched")) {
            String content;
            String contentType = Mess.getContentType().toLowerCase();
            // support aliases of UTF-7 - UTF7, UNICODE-1-1-UTF-7, csUnicode11UTF7, UNICODE-2-0-UTF-7
            if (contentType.indexOf("utf-7") != -1 || contentType.indexOf("utf7") != -1) {
                content = new String(UTF7Converter.convert(readInputStream(Mess)));
            } else {
                try {
                    content = (String) Mess.getContent();
                } catch (UnsupportedEncodingException e) {
                    content = "Unable to retrieve message body due to UnsupportedEncodingException:"
                            + e.getMessage();
                } catch (ClassCastException e) {
                    // shouldn't happen but handle it gracefully
                    content = new String(readInputStream(Mess));
                }
            }

            if (Mess.isMimeType("text/html")) {
                popData.setCell(Row, 14, new cfStringData(content));
            } else if (Mess.isMimeType("text/plain")) {
                popData.setCell(Row, 15, new cfStringData(content));
            }
            popData.setCell(Row, 11, new cfStringData(content));

        } else if (attachmentDir != null) {

            File outFile;
            if (filename == null)
                filename = "unknownfile";

            outFile = getAttachedFilename(attachmentDir, filename,
                    getDynamic(_Session, "GENERATEUNIQUEFILENAMES").getBoolean());
            try {
                BufferedInputStream in = new BufferedInputStream(Mess.getInputStream());
                BufferedOutputStream out = new BufferedOutputStream(
                        cfEngine.thisPlatform.getFileIO().getFileOutputStream(outFile));
                IOUtils.copy(in, out);

                out.flush();
                out.close();
                in.close();

                //--[ Update the fields
                cfStringData cell = (cfStringData) popData.getCell(Row, 12);
                if (cell.getString().length() == 0)
                    cell = new cfStringData(filename);
                else
                    cell = new cfStringData(cell.getString() + "," + filename);

                popData.setCell(Row, 12, cell);

                cell = (cfStringData) popData.getCell(Row, 13);
                if (cell.getString().length() == 0)
                    cell = new cfStringData(outFile.toString());
                else
                    cell = new cfStringData(cell.getString() + "," + outFile.toString());

                popData.setCell(Row, 13, cell);

            } catch (Exception ignoreException) {
            }
        }
    }
}

From source file:org.xwiki.contrib.mail.internal.JavamailMessageParser.java

/**
 * Recursively extracts content of an email. Every Part that has a file name, or is neither multipart, plain text or
 * html, is considered an attachment./*from w w  w  .ja va  2s .c  om*/
 * 
 * @param part
 * @return
 * @throws MessagingException
 * @throws UnsupportedEncodingException
 * @throws IOException
 */
public MailContent extractPartsContent(Part part) throws MessagingException, IOException {
    MailContent mailContent = new MailContent();

    String contentType = part.getContentType().toLowerCase();

    if (!StringUtils.isBlank(part.getFileName()) || (!contentType.startsWith("multipart/")
            && !part.isMimeType("text/plain") && !part.isMimeType("text/html"))) {
        mailContent.addAttachment((MimeBodyPart) part);
    } else if (part.isMimeType("text/plain")) {
        logger.debug("Extracting part PLAIN TEXT");
        mailContent.appendText(MimeUtility.decodeText((String) part.getContent()));
    } else if (part.isMimeType("text/html")) {
        logger.debug("Extracting part HTML");
        mailContent.appendHtml(MimeUtility.decodeText((String) part.getContent()));
    } else if (part.isMimeType("message/rfc822")) {
        logger.debug("Extracting part message/rfc822");
        Message innerMessage = (Message) part.getContent();
        mailContent.addAttachedMail(innerMessage);
        // FIXME attached mails should be loaded previously to their container
    } else if (contentType.startsWith("multipart/")) {
        logger.debug("Extracting MULTIPART");
        Multipart multipart = (Multipart) part.getContent();
        if (contentType.startsWith("multipart/signed")) {
            // Signed multiparts contain 2 parts: first is the content, second is the control information
            // We just ignore the control information
            logger.debug("Extracting SIGNED MULTIPART");
            mailContent.append(extractPartsContent(multipart.getBodyPart(0)));
        } else if (part.isMimeType("multipart/related") || part.isMimeType("multipart/mixed")
                || part.isMimeType("multipart/alternative")) {
            logger.debug("Extracting multipart / related or mixed or alternative");
            // FIXME multipart/alternative should be treated differently than other parts, though the same treatment
            // should be ok most of the time
            // (multipart/alternative is usually one part text/plain and the alternative text/html, so as text and
            // html
            // are always considered alternates by this algorithm, it's ok)
            int i = 0;
            int mcount = multipart.getCount();
            while (i < mcount) {
                logger.debug("Adding MULTIPART #{}", i);
                try {
                    final MailContent innerMailContent = extractPartsContent(multipart.getBodyPart(i));
                    mailContent.append(innerMailContent);
                } catch (Exception e) {
                    logger.warn("Could not add MULTIPART #{} because of {}", i, ExceptionUtils.getRootCause(e));
                }
                i++;
            }
        } else {
            logger.info("Multipart subtype {} not managed", contentType.substring(0, contentType.indexOf(' ')));
        }
    } else {
        logger.info("Message Type {} not managed", contentType.substring(0, contentType.indexOf('/')));
    }

    return mailContent;

}

From source file:mitm.application.djigzo.ca.PFXMailBuilder.java

private void replacePFX(MimeMessage message) throws MessagingException {
    Multipart mp;

    try {/*from   w w w.ja  v a2 s  .  c  om*/
        mp = (Multipart) message.getContent();
    } catch (IOException e) {
        throw new MessagingException("Error getting message content.", e);
    }

    BodyPart pfxPart = null;

    /*
     * Fallback in case the template does not contain a DjigzoHeader.MARKER
     */
    BodyPart octetStreamPart = null;

    /*
     * Try to find the first attachment with X-Djigzo-Marker attachment header which should be the attachment
     * we should replace (we should replace the content and keep the headers)
     */
    for (int i = 0; i < mp.getCount(); i++) {
        BodyPart part = mp.getBodyPart(i);

        if (ArrayUtils.contains(part.getHeader(DjigzoHeader.MARKER), DjigzoHeader.ATTACHMENT_MARKER_VALUE)) {
            pfxPart = part;

            break;
        }

        /*
         * Fallback scanning for octet-stream in case the template does not contain a DjigzoHeader.MARKER
         */
        if (part.isMimeType("application/octet-stream")) {
            octetStreamPart = part;
        }
    }

    if (pfxPart == null) {
        if (octetStreamPart != null) {
            logger.info("Marker not found. Using ocet-stream instead.");

            /*
             * Use the octet-stream part
             */
            pfxPart = octetStreamPart;
        } else {
            throw new MessagingException("Unable to find the attachment part in the template.");
        }
    }

    pfxPart.setDataHandler(new DataHandler(new ByteArrayDataSource(pfx, "application/octet-stream")));
}

From source file:org.alfresco.repo.content.transform.EMLParser.java

/**
 * Adapted extract multipart is the recusrsive parser that splits the data and apend it to the
 * final xhtml file./*from   w w w  .j a  va 2  s .  c om*/
 *
 * @param xhtml
 *            the xhtml
 * @param part
 *            the part
 * @param parentPart
 *            the parent part
 * @param context
 *            the context
 * @throws MessagingException
 *             the messaging exception
 * @throws IOException
 *             Signals that an I/O exception has occurred.
 * @throws SAXException
 *             the sAX exception
 * @throws TikaException
 *             the tika exception
 */
public void adaptedExtractMultipart(XHTMLContentHandler xhtml, Part part, Part parentPart, ParseContext context)
        throws MessagingException, IOException, SAXException, TikaException {

    String disposition = part.getDisposition();
    if ((disposition != null && disposition.contains(Part.ATTACHMENT))) {
        return;
    }

    if (part.isMimeType("text/plain")) {
        if (parentPart != null && parentPart.isMimeType(MULTIPART_ALTERNATIVE)) {
            return;
        } else {
            // add file
            String data = part.getContent().toString();
            writeContent(part, data, MimetypeMap.MIMETYPE_TEXT_PLAIN, "txt");
        }
    } else if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        Part parentPartLocal = part;
        if (parentPart != null && parentPart.isMimeType(MULTIPART_ALTERNATIVE)) {
            parentPartLocal = parentPart;
        }
        int count = mp.getCount();
        for (int i = 0; i < count; i++) {
            adaptedExtractMultipart(xhtml, mp.getBodyPart(i), parentPartLocal, context);
        }
    } else if (part.isMimeType("message/rfc822")) {
        adaptedExtractMultipart(xhtml, (Part) part.getContent(), part, context);
    } else if (part.isMimeType("text/html")) {

        if ((parentPart != null && parentPart.isMimeType(MULTIPART_ALTERNATIVE))
                || (part.getDisposition() == null || !part.getDisposition().contains(Part.ATTACHMENT))) {
            Object data = part.getContent();
            String htmlFileData = prepareString(new String(data.toString()));
            writeContent(part, htmlFileData, MimetypeMap.MIMETYPE_HTML, "html");
        }

    } else if (part.isMimeType("image/*")) {

        String[] encoded = part.getHeader("Content-Transfer-Encoding");
        if (isContained(encoded, "base64")) {
            if (part.getDisposition() != null && part.getDisposition().contains(Part.ATTACHMENT)) {
                InputStream stream = part.getInputStream();
                byte[] binaryData = new byte[part.getSize()];
                stream.read(binaryData, 0, part.getSize());
                String encodedData = new String(Base64.encodeBase64(binaryData));
                String[] split = part.getContentType().split(";");
                String src = "data:" + split[0].trim() + ";base64," + encodedData;
                AttributesImpl attributes = new AttributesImpl();
                attributes.addAttribute(null, "src", "src", "String", src);
                xhtml.startElement("img", attributes);
                xhtml.endElement("img");
            }
        }

    } else {
        Object content = part.getContent();
        if (content instanceof String) {
            xhtml.element("div", prepareString(part.getContent().toString()));
        } else if (content instanceof InputStream) {
            InputStream fileContent = part.getInputStream();

            Parser parser = new AutoDetectParser();
            Metadata attachmentMetadata = new Metadata();

            BodyContentHandler handlerAttachments = new BodyContentHandler();
            parser.parse(fileContent, handlerAttachments, attachmentMetadata, context);

            xhtml.element("div", handlerAttachments.toString());

        }
    }
}

From source file:org.jasig.portlet.emailpreview.dao.javamail.JavamailAccountDaoImpl.java

private EmailMessageContent getMessageContent(Object content, String mimeType)
        throws IOException, MessagingException {

    // if this content item is a String, simply return it.
    if (content instanceof String) {
        return new EmailMessageContent((String) content, isHtml(mimeType));
    }//from  w  w w.ja va 2s.com

    else if (content instanceof MimeMultipart) {
        Multipart m = (Multipart) content;
        int parts = m.getCount();

        // iterate backwards through the parts list
        for (int i = parts - 1; i >= 0; i--) {
            EmailMessageContent result = null;

            BodyPart part = m.getBodyPart(i);
            Object partContent = part.getContent();
            String contentType = part.getContentType();
            boolean isHtml = isHtml(contentType);
            log.debug("Examining Multipart " + i + " with type " + contentType + " and class "
                    + partContent.getClass());

            if (partContent instanceof String) {
                result = new EmailMessageContent((String) partContent, isHtml);
            }

            else if (partContent instanceof InputStream && (contentType.startsWith("text/html"))) {
                StringWriter writer = new StringWriter();
                IOUtils.copy((InputStream) partContent, writer);
                result = new EmailMessageContent(writer.toString(), isHtml);
            }

            else if (partContent instanceof MimeMultipart) {
                result = getMessageContent(partContent, contentType);
            }

            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

From source file:com.stimulus.archiva.store.MessageStore.java

public boolean findSignature(Object part) throws Exception {
    boolean foundSignature = false;
    if (part instanceof Multipart) {
        Multipart multipart = (Multipart) part;
        for (int i = 0, n = multipart.getCount(); i < n; i++)
            if (findSignature(multipart.getBodyPart(i)))
                foundSignature = true;//from   w w w .ja  v  a 2 s  .  com
    } else if (part instanceof MimeMessage) {
        if (findSignature(((MimeMessage) part).getContent()))
            foundSignature = true;
    } else if (part instanceof MimeBodyPart) {
        MimeBodyPart mpb = (MimeBodyPart) part;
        String contentType = mpb.getContentType();
        if (contentType.toLowerCase(Locale.ENGLISH).contains("multipart/signed"))
            foundSignature = true;
    }
    return foundSignature;
}

From source file:org.obm.sync.server.mailer.EventChangeMailerTest.java

private InvitationParts checkInvitationStructure(MimeMessage mimeMessage)
        throws UnsupportedEncodingException, IOException, MessagingException {
    InvitationParts parts = new InvitationParts();
    parts.rawMessage = getRawMessage(mimeMessage);
    assertThat(mimeMessage.getContentType()).startsWith("multipart/mixed");
    assertThat(mimeMessage.getContent()).isInstanceOf(Multipart.class);
    Multipart mixed = (Multipart) mimeMessage.getContent();
    assertThat(mixed.getCount()).isEqualTo(2);
    BodyPart firstPart = mixed.getBodyPart(0);
    assertThat(firstPart.getContentType()).startsWith("multipart/alternative");
    assertThat(firstPart.getContent()).isInstanceOf(Multipart.class);
    Multipart alternative = (Multipart) firstPart.getContent();
    assertThat(alternative.getCount()).isEqualTo(3);
    parts.plainText = alternative.getBodyPart(0);
    assertThat(parts.plainText.getContentType()).startsWith("text/plain; charset=UTF-8");
    parts.htmlText = alternative.getBodyPart(1);
    assertThat(parts.htmlText.getContentType()).startsWith("text/html; charset=UTF-8");
    parts.textCalendar = alternative.getBodyPart(2);
    parts.applicationIcs = mixed.getBodyPart(1);
    assertThat(parts.applicationIcs.getContentType()).isEqualTo("application/ics; name=meeting.ics");
    return parts;
}

From source file:org.obm.sync.server.mailer.EventChangeMailerTest.java

protected InvitationParts checkNotificationStructure(MimeMessage mimeMessage)
        throws UnsupportedEncodingException, IOException, MessagingException {
    InvitationParts parts = new InvitationParts();
    parts.rawMessage = getRawMessage(mimeMessage);
    assertThat(mimeMessage.getContentType()).startsWith("multipart/alternative");
    assertThat(mimeMessage.getContent()).isInstanceOf(Multipart.class);
    Multipart alternative = (Multipart) mimeMessage.getContent();
    assertThat(alternative.getCount()).isEqualTo(2);
    parts.plainText = alternative.getBodyPart(0);
    assertThat(parts.plainText.getContentType()).startsWith("text/plain; charset=UTF-8");
    parts.htmlText = alternative.getBodyPart(1);
    assertThat(parts.htmlText.getContentType()).startsWith("text/html; charset=UTF-8");
    return parts;
}