Search in sources :

Example 16 with ByteArrayDataSource

use of jakarta.mail.util.ByteArrayDataSource in project exist by eXist-db.

the class SendEmailFunction method parseMessageElement.

/**
 * Constructs a mail Object from an XML representation of an email
 * <p>
 * The XML email Representation is expected to look something like this
 *
 * <mail>
 * <from></from>
 * <reply-to></reply-to>
 * <to></to>
 * <cc></cc>
 * <bcc></bcc>
 * <subject></subject>
 * <message>
 * <text charset="" encoding=""></text>
 * <xhtml charset="" encoding=""></xhtml>
 * <generic charset="" type="" encoding=""></generic>
 * </message>
 * <attachment mimetype="" filename=""></attachment>
 * </mail>
 *
 * @param mailElements The XML mail Node
 * @throws IOException          if an I/O error occurs
 * @throws MessagingException   if an email error occurs
 * @throws TransformerException if a transformation error occurs
 * @return A mail Object representing the XML mail Node
 */
private Message[] parseMessageElement(final Session session, final Element[] mailElements) throws IOException, MessagingException, TransformerException {
    Message[] mails = new Message[mailElements.length];
    int i = 0;
    for (final Element mailElement : mailElements) {
        // Make sure that message has a Mail node
        if ("mail".equals(mailElement.getLocalName())) {
            // New message Object
            // create a message
            final MimeMessage msg = new MimeMessage(session);
            boolean fromWasSet = false;
            final List<InternetAddress> replyTo = new ArrayList<>();
            MimeBodyPart body = null;
            Multipart multibody = null;
            final List<MimeBodyPart> attachments = new ArrayList<>();
            String firstContent = null;
            String firstContentType = null;
            String firstCharset = null;
            String firstEncoding = null;
            // Get the First Child
            Node child = mailElement.getFirstChild();
            while (child != null) {
                // Parse each of the child nodes
                if (Node.ELEMENT_NODE == child.getNodeType() && child.hasChildNodes()) {
                    switch(child.getLocalName()) {
                        case "from":
                            // set the from and to address
                            final InternetAddress[] addressFrom = { new InternetAddress(child.getFirstChild().getNodeValue()) };
                            msg.addFrom(addressFrom);
                            fromWasSet = true;
                            break;
                        case "reply-to":
                            // As we can only set the reply-to, not add them, let's keep
                            // all of them in a list
                            replyTo.add(new InternetAddress(child.getFirstChild().getNodeValue()));
                            break;
                        case "to":
                            msg.addRecipient(Message.RecipientType.TO, new InternetAddress(child.getFirstChild().getNodeValue()));
                            break;
                        case "cc":
                            msg.addRecipient(Message.RecipientType.CC, new InternetAddress(child.getFirstChild().getNodeValue()));
                            break;
                        case "bcc":
                            msg.addRecipient(Message.RecipientType.BCC, new InternetAddress(child.getFirstChild().getNodeValue()));
                            break;
                        case "subject":
                            msg.setSubject(child.getFirstChild().getNodeValue());
                            break;
                        case "header":
                            // Optional : You can also set your custom headers in the Email if you Want
                            msg.addHeader(((Element) child).getAttribute("name"), child.getFirstChild().getNodeValue());
                            break;
                        case "message":
                            // If the message node, then parse the child text and xhtml nodes
                            Node bodyPart = child.getFirstChild();
                            while (bodyPart != null) {
                                if (Node.ELEMENT_NODE != bodyPart.getNodeType()) {
                                    continue;
                                }
                                final Element elementBodyPart = (Element) bodyPart;
                                String content = null;
                                String contentType = null;
                                switch(bodyPart.getLocalName()) {
                                    case "text":
                                        // Setting the Subject and Content Type
                                        content = bodyPart.getFirstChild().getNodeValue();
                                        contentType = "plain";
                                        break;
                                    case "xhtml":
                                        // Convert everything inside <xhtml></xhtml> to text
                                        final Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
                                        final DOMSource source = new DOMSource(bodyPart.getFirstChild());
                                        try (final StringWriter strWriter = new StringWriter()) {
                                            final StreamResult result = new StreamResult(strWriter);
                                            transformer.transform(source, result);
                                            content = strWriter.toString();
                                        }
                                        contentType = "html";
                                        break;
                                    case "generic":
                                        // Setting the Subject and Content Type
                                        content = elementBodyPart.getFirstChild().getNodeValue();
                                        contentType = elementBodyPart.getAttribute("type");
                                        break;
                                }
                                // Now, time to store it
                                if (content != null && contentType != null && !contentType.isEmpty()) {
                                    String charset = elementBodyPart.getAttribute("charset");
                                    String encoding = elementBodyPart.getAttribute("encoding");
                                    if (body != null && multibody == null) {
                                        multibody = new MimeMultipart("alternative");
                                        multibody.addBodyPart(body);
                                    }
                                    if (StringUtils.isEmpty(charset)) {
                                        charset = "UTF-8";
                                    }
                                    if (StringUtils.isEmpty(encoding)) {
                                        encoding = "quoted-printable";
                                    }
                                    if (body == null) {
                                        firstContent = content;
                                        firstCharset = charset;
                                        firstContentType = contentType;
                                        firstEncoding = encoding;
                                    }
                                    body = new MimeBodyPart();
                                    body.setText(content, charset, contentType);
                                    if (encoding != null) {
                                        body.setHeader("Content-Transfer-Encoding", encoding);
                                    }
                                    if (multibody != null) {
                                        multibody.addBodyPart(body);
                                    }
                                }
                                // next body part
                                bodyPart = bodyPart.getNextSibling();
                            }
                            break;
                        case "attachment":
                            final Element attachment = (Element) child;
                            final MimeBodyPart part;
                            // if mimetype indicates a binary resource, assume the content is base64 encoded
                            if (MimeTable.getInstance().isTextContent(attachment.getAttribute("mimetype"))) {
                                part = new MimeBodyPart();
                            } else {
                                part = new PreencodedMimeBodyPart("base64");
                            }
                            final StringBuilder content = new StringBuilder();
                            Node attachChild = attachment.getFirstChild();
                            while (attachChild != null) {
                                if (Node.ELEMENT_NODE == attachChild.getNodeType()) {
                                    final Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
                                    final DOMSource source = new DOMSource(attachChild);
                                    try (final StringWriter strWriter = new StringWriter()) {
                                        final StreamResult result = new StreamResult(strWriter);
                                        transformer.transform(source, result);
                                        content.append(strWriter);
                                    }
                                } else {
                                    content.append(attachChild.getNodeValue());
                                }
                                attachChild = attachChild.getNextSibling();
                            }
                            part.setDataHandler(new DataHandler(new ByteArrayDataSource(content.toString(), attachment.getAttribute("mimetype"))));
                            part.setFileName(attachment.getAttribute("filename"));
                            // part.setHeader("Content-Transfer-Encoding", "base64");
                            attachments.add(part);
                            break;
                    }
                }
                // next node
                child = child.getNextSibling();
            }
            // Lost from
            if (!fromWasSet) {
                msg.setFrom();
            }
            msg.setReplyTo(replyTo.toArray(new InternetAddress[0]));
            // Preparing content and attachments
            if (!attachments.isEmpty()) {
                if (multibody == null) {
                    multibody = new MimeMultipart("mixed");
                    if (body != null) {
                        multibody.addBodyPart(body);
                    }
                } else {
                    final MimeMultipart container = new MimeMultipart("mixed");
                    final MimeBodyPart containerBody = new MimeBodyPart();
                    containerBody.setContent(multibody);
                    container.addBodyPart(containerBody);
                    multibody = container;
                }
                for (final MimeBodyPart part : attachments) {
                    multibody.addBodyPart(part);
                }
            }
            // And now setting-up content
            if (multibody != null) {
                msg.setContent(multibody);
            } else if (body != null) {
                msg.setText(firstContent, firstCharset, firstContentType);
                if (firstEncoding != null) {
                    msg.setHeader("Content-Transfer-Encoding", firstEncoding);
                }
            }
            msg.saveChanges();
            mails[i++] = msg;
        }
    }
    if (i != mailElements.length) {
        mails = Arrays.copyOf(mails, i);
    }
    return mails;
}
Also used : DOMSource(javax.xml.transform.dom.DOMSource) Transformer(javax.xml.transform.Transformer) StreamResult(javax.xml.transform.stream.StreamResult) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) DataHandler(jakarta.activation.DataHandler) ByteArrayDataSource(jakarta.mail.util.ByteArrayDataSource)

Example 17 with ByteArrayDataSource

use of jakarta.mail.util.ByteArrayDataSource in project simple-java-mail by bbottema.

the class FullEmailDemoApp method testMixedRelatedAlternativeIncludingCalendarAndMessageParsingUsingVariousMailers.

private static void testMixedRelatedAlternativeIncludingCalendarAndMessageParsingUsingVariousMailers() throws IOException {
    final String resourcesPathOnDisk = determineResourceFolder("simple-java-mail") + "/test/resources";
    final EmailPopulatingBuilder emailPopulatingBuilderNormal = EmailBuilder.startingBlank().withEmbeddedImageAutoResolutionForFiles(true).withEmbeddedImageAutoResolutionForClassPathResources(true).withEmbeddedImageAutoResolutionForURLs(true);
    emailPopulatingBuilderNormal.from("Simple Java Mail demo", "simplejavamail@demo.app");
    // don't forget to add your own address here ->
    emailPopulatingBuilderNormal.to("C.Cane", YOUR_GMAIL_ADDRESS);
    emailPopulatingBuilderNormal.withPlainText("Plain text content (ignored in favor of HTML by modern browsers)");
    emailPopulatingBuilderNormal.withHTMLText("<p>This is an email with \"mixed\", \"related\" and \"alternative\" content: it contains a plain " + "text part (ignored in favor of HTML by modern clients), an HTML content part (this HTML text) which references a related " + "content part (the embedded image) and a iCalendar content part. In addition this email contains a separate attachment as " + "well.</p>" + "<ol>" + "   <li>Image embedded with fixed cid and hardcoded datasource: <img width=25 src='cid:thumbsup'></li>" + "   <li>Image embedded with generated cid datasource resolved from classpath:<img src='/test-dynamicembedded-image/excellent.png' style='width:25px'></li>" + "   <li>Image embedded with generated cid datasource resolved from disk:<img src='" + resourcesPathOnDisk + "/test-dynamicembedded-image/excellent.png' style='width:25px'></li>" + "   <li>Image embedded with generated cid datasource resolved from URL!:<img src='https://www.simplejavamail.org/assets/github-ribbon-topright@2x.png' style='width:32px' title='Fork me on GitHub'></li>" + "</ol>" + "<p><b>Formal structure:</b><br>" + "<ul>" + "   <li>mixed (root)<ul>" + "   	<li>related<ul>" + "   		<li>alternative<ul>" + "   			<li>plain text</li>" + "				<li>HTML text</li>" + "			</ul></li>" + "			<li>embeddable images (1x fixed: cid:thumbsup and 3x dynamically resolved)</li>" + "		</ul></li>" + "		<li>attachment</li>" + "	</ul></li>" + // makes it alternative
    "</ul></p>");
    emailPopulatingBuilderNormal.withSubject("Email with mixed + related + alternative content (including iCalendar event)");
    // add two text files in different ways and a black thumbs up embedded image ->
    emailPopulatingBuilderNormal.withAttachment("dresscode.txt", new ByteArrayDataSource("Black Tie Optional", "text/plain"));
    emailPopulatingBuilderNormal.withAttachment("location.txt", "On the moon!".getBytes(defaultCharset()), "text/plain");
    emailPopulatingBuilderNormal.withAttachment("special_łąąśćńółęĄŻŹĆŃÓŁĘ.txt", "doorcode: Ken sent me".getBytes(defaultCharset()), "text/plain");
    emailPopulatingBuilderNormal.withEmbeddedImage("thumbsup", produceThumbsUpImage(), "image/png");
    emailPopulatingBuilderNormal.withCalendarText(CalendarMethod.REQUEST, CalendarHelper.createCalendarEvent());
    // let's try producing and then consuming a MimeMessage ->
    Email emailNormal = emailPopulatingBuilderNormal.buildEmail();
    final MimeMessage mimeMessage = EmailConverter.emailToMimeMessage(emailNormal);
    final Email emailFromMimeMessage = EmailConverter.mimeMessageToEmail(mimeMessage);
    mailerSMTPBuilder.buildMailer().sendMail(emailNormal);
    mailerTLSBuilder.buildMailer().sendMail(emailNormal);
    mailerSSLBuilder.buildMailer().sendMail(emailNormal);
    // should produce the exact same result as emailPopulatingBuilderNormal!
    mailerTLSBuilder.buildMailer().sendMail(emailFromMimeMessage);
}
Also used : Email(org.simplejavamail.api.email.Email) MimeMessage(jakarta.mail.internet.MimeMessage) EmailPopulatingBuilder(org.simplejavamail.api.email.EmailPopulatingBuilder) ByteArrayDataSource(jakarta.mail.util.ByteArrayDataSource)

Example 18 with ByteArrayDataSource

use of jakarta.mail.util.ByteArrayDataSource in project simple-java-mail by bbottema.

the class MimeMessageHelperTest method getDataSource.

private ByteArrayDataSource getDataSource(@Nullable String name) throws IOException {
    ByteArrayDataSource ds = new ByteArrayDataSource("", "text/text");
    ds.setName(name);
    return ds;
}
Also used : ByteArrayDataSource(jakarta.mail.util.ByteArrayDataSource)

Example 19 with ByteArrayDataSource

use of jakarta.mail.util.ByteArrayDataSource in project simple-java-mail by bbottema.

the class MimeMessageParserTest method testMoveInvalidEmbeddedResourcesToAttachments_HtmlButNoInvalid.

@Test
public void testMoveInvalidEmbeddedResourcesToAttachments_HtmlButNoInvalid() throws IOException {
    ParsedMimeMessageComponents parsedComponents = new ParsedMimeMessageComponents();
    parsedComponents.htmlContent.append("blah moo1 blah html");
    parsedComponents.cidMap.put("moo1", new ByteArrayDataSource("moomoo", "text/plain"));
    parsedComponents.cidMap.put("moo2", new ByteArrayDataSource("moomoo", "text/plain"));
    moveInvalidEmbeddedResourcesToAttachments(parsedComponents);
    assertThat(parsedComponents.cidMap).isEmpty();
    assertThat(parsedComponents.attachmentList).extracting("key").containsOnly("moo1", "moo2");
}
Also used : ParsedMimeMessageComponents(org.simplejavamail.converter.internal.mimemessage.MimeMessageParser.ParsedMimeMessageComponents) ByteArrayDataSource(jakarta.mail.util.ByteArrayDataSource) Test(org.junit.Test)

Example 20 with ByteArrayDataSource

use of jakarta.mail.util.ByteArrayDataSource in project simple-java-mail by bbottema.

the class SMIMESupport method handleLiberatedContent.

@Nullable
private AttachmentResource handleLiberatedContent(final Object content) throws MessagingException, IOException {
    if (content instanceof MimeMultipart) {
        final ByteArrayOutputStream os = new ByteArrayOutputStream();
        final MimeMessage decryptedMessage = new MimeMessage((Session) null) {

            @Override
            protected void updateMessageID() throws MessagingException {
                setHeader("Message-ID", SMIME_ATTACHMENT_MESSAGE_ID);
            }
        };
        decryptedMessage.setContent((Multipart) content);
        decryptedMessage.writeTo(os);
        return new AttachmentResource("signed-email.eml", new ByteArrayDataSource(os.toByteArray(), "message/rfc822"));
    }
    LOGGER.warn("S/MIME signed content type not recognized, please raise an issue for " + content.getClass());
    return null;
}
Also used : AttachmentResource(org.simplejavamail.api.email.AttachmentResource) MimeMultipart(jakarta.mail.internet.MimeMultipart) MimeMessage(jakarta.mail.internet.MimeMessage) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteArrayDataSource(jakarta.mail.util.ByteArrayDataSource) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

ByteArrayDataSource (jakarta.mail.util.ByteArrayDataSource)35 Test (org.junit.Test)16 MimeMultipart (jakarta.mail.internet.MimeMultipart)11 DataHandler (jakarta.activation.DataHandler)8 InputStream (java.io.InputStream)7 MimeMessage (jakarta.mail.internet.MimeMessage)6 DataSource (jakarta.activation.DataSource)5 MimeBodyPart (jakarta.mail.internet.MimeBodyPart)5 BufferedInputStream (java.io.BufferedInputStream)5 HttpServletResponse (jakarta.servlet.http.HttpServletResponse)4 Response (jakarta.ws.rs.core.Response)4 Email (org.simplejavamail.api.email.Email)4 MessagingException (jakarta.mail.MessagingException)3 File (java.io.File)3 IOException (java.io.IOException)3 NamedDataSource (org.simplejavamail.internal.util.NamedDataSource)3 BodyPart (jakarta.mail.BodyPart)2 Multipart (jakarta.mail.Multipart)2 InternetAddress (jakarta.mail.internet.InternetAddress)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2