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;
}
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);
}
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;
}
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");
}
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;
}
Aggregations