public InputStream getBodyInputStream() { try { return ((SingleBody) message.getBody()).getInputStream(); } catch (IOException e) { return null; } }
/** * Creates a new <code>Message</code> from the specified * <code>Message</code>. The <code>Message</code> instance is * initialized with copies of header and body of the specified * <code>Message</code>. The parent entity of the new message is * <code>null</code>. * * @param other * message to copy. * @throws UnsupportedOperationException * if <code>other</code> contains a {@link SingleBody} that * does not support the {@link SingleBody#copy() copy()} * operation. * @throws IllegalArgumentException * if <code>other</code> contains a <code>Body</code> that * is neither a {@link MessageImpl}, {@link Multipart} or * {@link SingleBody}. */ public Message copy(Message other) { MessageImpl copy = newMessageImpl(); if (other.getHeader() != null) { copy.setHeader(copy(other.getHeader())); } if (other.getBody() != null) { copy.setBody(copy(other.getBody())); } return copy; }
public static Envelope fromMime4JMessage(org.apache.james.mime4j.dom.Message mime4JMessage) { MailAddress sender = mime4JMessage.getFrom() .stream() .findAny() .map(Mailbox::getAddress) .map(Throwing.function(MailAddress::new)) .orElseThrow(() -> new RuntimeException("Sender is mandatory")); Stream<MailAddress> to = emailersToMailAddresses(mime4JMessage.getTo()); Stream<MailAddress> cc = emailersToMailAddresses(mime4JMessage.getCc()); Stream<MailAddress> bcc = emailersToMailAddresses(mime4JMessage.getBcc()); return new Envelope(sender, StreamUtils.flatten(Stream.of(to, cc, bcc)) .collect(Guavate.toImmutableSet())); }
/** * Parse a message and return a simple {@link String} representation of some important fields. * * @param messageBytes the message as {@link java.io.InputStream} * @return String * @throws IOException * @throws MimeException */ private static String messageSummary(InputStream messageBytes) throws IOException, MimeException { MessageBuilder builder = new DefaultMessageBuilder(); Message message = builder.parseMessage(messageBytes); return String.format("\nMessage %s \n" + "Sent by:\t%s\n" + "To:\t%s\n", message.getSubject(), message.getSender(), message.getTo()); } }
@VisibleForTesting Optional<Entity> extractReport(Message message) { LOGGER.debug("Extracting report"); if (!message.isMultipart()) { LOGGER.debug("MDN Message must be multipart"); return Optional.empty(); } List<Entity> bodyParts = ((Multipart) message.getBody()).getBodyParts(); if (bodyParts.size() < 2) { LOGGER.debug("MDN Message must contain at least two parts"); return Optional.empty(); } Entity report = bodyParts.get(1); if (!isDispositionNotification(report)) { LOGGER.debug("MDN Message second part must be of type " + MESSAGE_DISPOSITION_NOTIFICATION); return Optional.empty(); } return Optional.of(report); }
public Message fromMetaDataWithContent(MetaDataWithContent message) throws MailboxException { org.apache.james.mime4j.dom.Message mimeMessage = parse(message); MessageContent messageContent = extractContent(mimeMessage); Optional<String> htmlBody = messageContent.getHtmlBody(); Optional<String> mainTextContent = mainTextContent(messageContent); Optional<String> textBody = computeTextBodyIfNeeded(messageContent, mainTextContent); String preview = messagePreview.compute(mainTextContent); return Message.builder() .id(message.getMessageId()) .blobId(BlobId.of(blobManager.toBlobId(message.getMessageId()))) .threadId(message.getMessageId().serialize()) .mailboxIds(message.getMailboxIds()) .inReplyToMessageId(getHeader(mimeMessage, "in-reply-to")) .keywords(message.getKeywords()) .subject(Strings.nullToEmpty(mimeMessage.getSubject()).trim()) .headers(toMap(mimeMessage.getHeader().getFields())) .from(firstFromMailboxList(mimeMessage.getFrom())) .to(fromAddressList(mimeMessage.getTo())) .cc(fromAddressList(mimeMessage.getCc())) .bcc(fromAddressList(mimeMessage.getBcc())) .replyTo(fromAddressList(mimeMessage.getReplyTo())) .size(message.getSize()) .date(getDateFromHeaderOrInternalDateOtherwise(mimeMessage, message)) .textBody(textBody) .htmlBody(htmlBody) .preview(preview) .attachments(getAttachments(message.getAttachments())) .build(); }
private Optional<Mailbox> getAddressForHeader(Message originalMessage, String fieldName) { return Optional.ofNullable(originalMessage.getHeader() .getFields(fieldName)) .orElse(ImmutableList.of()) .stream() .map(field -> AddressListFieldLenientImpl.PARSER.parse(field, new DecodeMonitor())) .findFirst() .map(AddressListField::getAddressList) .map(AddressList::flatten) .map(MailboxList::stream) .orElse(Stream.of()) .findFirst(); }
@Test public void convertToMimeShouldSetEmptyTextBodyWhenProvided() { // Given MIMEMessageConverter sut = new MIMEMessageConverter(); TextBody expected = new BasicBodyFactory().textBody("", StandardCharsets.UTF_8); CreationMessage testMessage = CreationMessage.builder() .mailboxId("dead-bada55") .subject("subject") .from(DraftEmailer.builder().name("sender").build()) .textBody("") .build(); // When Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of()); // Then assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset"); assertThat(result.getMimeType()).isEqualTo("text/plain"); }
@Test public void convertToMimeShouldGenerateMultipartWhenHtmlBodyAndTextBodyProvided() throws Exception { // Given MIMEMessageConverter sut = new MIMEMessageConverter(); CreationMessage testMessage = CreationMessage.builder() .mailboxId("dead-bada55") .subject("subject") .from(DraftEmailer.builder().name("sender").build()) .textBody("Hello all!") .htmlBody("Hello <b>all</b>!") .build(); // When Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of()); // Then assertThat(result.getBody()).isInstanceOf(Multipart.class); assertThat(result.isMultipart()).isTrue(); assertThat(result.getMimeType()).isEqualTo("multipart/alternative"); Multipart typedResult = (Multipart)result.getBody(); assertThat(typedResult.getBodyParts()).hasSize(2); }
@Test public void convertToMimeShouldFilterGeneratedHeadersWhenProvided() { // Given MIMEMessageConverter sut = new MIMEMessageConverter(); String joesEmail = "joe@example.com"; CreationMessage messageHavingInReplyTo = CreationMessage.builder() .from(DraftEmailer.builder().email(joesEmail).name("joe").build()) .headers(ImmutableMap.of("From", "hacker@example.com", "VALID", "valid header value")) .mailboxIds(ImmutableList.of("dead-beef-1337")) .subject("subject") .build(); // When Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of()); // Then assertThat(result.getFrom()).extracting(Mailbox::getAddress) .allMatch(f -> f.equals(joesEmail)); assertThat(result.getHeader().getFields("VALID")).extracting(Field::getBody) .containsOnly("valid header value"); assertThat(result.getHeader().getFields("From")).extracting(Field::getBody) .containsOnly("joe <joe@example.com>"); }
@Test public void convertToMimeShouldSetBothFromAndSenderHeaders() { // Given MIMEMessageConverter sut = new MIMEMessageConverter(); String joesEmail = "joe@example.com"; CreationMessage testMessage = CreationMessage.builder() .mailboxIds(ImmutableList.of("deadbeef-dead-beef-dead-beef")) .subject("subject") .from(DraftEmailer.builder().email(joesEmail).name("joe").build()) .build(); // When Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of()); // Then assertThat(result.getFrom()).extracting(Mailbox::getAddress).allMatch(f -> f.equals(joesEmail)); assertThat(result.getSender().getAddress()).isEqualTo(joesEmail); }
@Test public void generateMDNMessageShouldUseDispositionHeaders() throws Exception { String senderAddress = "sender@local"; Message originMessage = Message.Builder.of() .setMessageId("45554@local.com") .setFrom(senderAddress) .setBody("body", StandardCharsets.UTF_8) .addField(new RawField(JmapMDN.RETURN_PATH, "<" + senderAddress + ">")) .addField(new RawField(JmapMDN.DISPOSITION_NOTIFICATION_TO, "<" + senderAddress + ">")) .build(); assertThat( MDN.generateMDNMessage(originMessage, MAILBOX_SESSION) .getTo()) .extracting(address -> (Mailbox) address) .extracting(Mailbox::getAddress) .containsExactly(senderAddress); }
/** * Make sure to dispose the message once used. */ public void dispose() { this.message.dispose(); } }
assertThat(result.getBody()).isInstanceOf(Multipart.class); assertThat(result.isMultipart()).isTrue(); Multipart typedResult = (Multipart)result.getBody(); assertThat(typedResult.getBodyParts()).hasSize(2); Entity attachmentPart = typedResult.getBodyParts().get(1);
/** * @see org.apache.james.jdkim.api.Headers#getFields() */ public List<String> getFields() { List<Field> res = message.getHeader().getFields(); return convertFields(res); }
@Test public void convertToMimeShouldSetEmptyHtmlBodyWhenProvided() { // Given MIMEMessageConverter sut = new MIMEMessageConverter(); TextBody expected = new BasicBodyFactory().textBody("", StandardCharsets.UTF_8); CreationMessage testMessage = CreationMessage.builder() .mailboxId("dead-bada55") .subject("subject") .from(DraftEmailer.builder().name("sender").build()) .htmlBody("") .build(); // When Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of()); // Then assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset"); assertThat(result.getMimeType()).isEqualTo("text/html"); }
@Test public void convertToMimeShouldFilterGeneratedHeadersRegardlessOfCaseWhenProvided() { // Given MIMEMessageConverter sut = new MIMEMessageConverter(); String joesEmail = "joe@example.com"; CreationMessage messageHavingInReplyTo = CreationMessage.builder() .from(DraftEmailer.builder().email(joesEmail).name("joe").build()) .headers(ImmutableMap.of("frOM", "hacker@example.com", "VALID", "valid header value")) .mailboxIds(ImmutableList.of("dead-beef-1337")) .subject("subject") .build(); // When Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of()); // Then assertThat(result.getFrom()).extracting(Mailbox::getAddress) .allMatch(f -> f.equals(joesEmail)); assertThat(result.getHeader().getFields("VALID")).extracting(Field::getBody) .containsOnly("valid header value"); assertThat(result.getHeader().getFields("From")).extracting(Field::getBody) .containsOnly("joe <joe@example.com>"); }
public static void main(String[] args) throws Exception { // 1) start with an empty message Message message = MessageBuilder.create() // 2) set header fields // Date and From are required fields // Message-ID should be present .setFrom("John Doe <jdoe@machine.example>") .setTo("Mary Smith <mary@example.net>") .setSubject("Saying Hello") .setDate(new Date()) .generateMessageId(InetAddress.getLocalHost().getCanonicalHostName()) .setBody("This is a message just to say hello.\r\nSo, \"Hello\".", Charsets.ISO_8859_1) .build(); try { // 4) print message to standard output MessageWriter writer = new DefaultMessageWriter(); writer.writeMessage(message, System.out); } finally { // 5) message is no longer needed and should be disposed of message.dispose(); } } }
public MessageContent extract(org.apache.james.mime4j.dom.Message message) throws IOException { Body body = message.getBody(); if (body instanceof TextBody) { return parseTextBody(message, (TextBody)body); } if (body instanceof Multipart) { return parseMultipart(message, (Multipart)body); } return MessageContent.empty(); }
public Builder copy(Message other) { if (other == null) { return this; } clearFields(); final Header otherHeader = other.getHeader(); if (otherHeader != null) { final List<Field> otherFields = otherHeader.getFields(); for (Field field: otherFields) { addField(field); } } Body body = null; Body otherBody = other.getBody(); if (otherBody instanceof Message) { body = Builder.of((Message) otherBody).build(); } else if (otherBody instanceof Multipart) { body = MultipartBuilder.createCopy((Multipart) otherBody).build(); } else if (otherBody instanceof SingleBody) { body = ((SingleBody) otherBody).copy(); } setBody(body); return this; }