Skip to content

Commit

Permalink
Merge pull request #346 from drencrom/develop
Browse files Browse the repository at this point in the history
Add option to parse MimeMessage without loading attachment data
  • Loading branch information
bbottema authored Dec 24, 2021
2 parents deb937b + 87c5e8a commit 7ff414a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ public static Email mimeMessageToEmail(@NotNull final MimeMessage mimeMessage, @
return mimeMessageToEmailBuilder(mimeMessage, pkcs12Config).buildEmail();
}

/**
* Delegates to {@link #mimeMessageToEmailBuilder(MimeMessage, Pkcs12Config, boolean)}.
*/
@NotNull
public static Email mimeMessageToEmail(@NotNull final MimeMessage mimeMessage, @Nullable final Pkcs12Config pkcs12Config, boolean attachmentData) {
return mimeMessageToEmailBuilder(mimeMessage, pkcs12Config, attachmentData).buildEmail();
}

/**
* Delegates to {@link #mimeMessageToEmailBuilder(MimeMessage, Pkcs12Config)}.
*/
Expand All @@ -88,16 +96,26 @@ public static EmailPopulatingBuilder mimeMessageToEmailBuilder(@NotNull final Mi
return mimeMessageToEmailBuilder(mimeMessage, null);
}

/**
* Delegates to {@link #mimeMessageToEmailBuilder(MimeMessage, Pkcs12Config, boolean)}.
*/
@NotNull
public static EmailPopulatingBuilder mimeMessageToEmailBuilder(@NotNull final MimeMessage mimeMessage, @Nullable final Pkcs12Config pkcs12Config) {
return mimeMessageToEmailBuilder(mimeMessage, pkcs12Config, true);
}

/**
* @param mimeMessage The MimeMessage from which to create the {@link Email}.
* @param pkcs12Config Private key store for decrypting S/MIME encrypted attachments
* (only needed when the message is encrypted rather than just signed).
* @param attachmentData When false only the names of the attachments are retrieved but no data
*/
@NotNull
public static EmailPopulatingBuilder mimeMessageToEmailBuilder(@NotNull final MimeMessage mimeMessage, @Nullable final Pkcs12Config pkcs12Config) {
public static EmailPopulatingBuilder mimeMessageToEmailBuilder(@NotNull final MimeMessage mimeMessage, @Nullable final Pkcs12Config pkcs12Config,
boolean attachmentData) {
checkNonEmptyArgument(mimeMessage, "mimeMessage");
final EmailPopulatingBuilder builder = EmailBuilder.ignoringDefaults().startingBlank();
final ParsedMimeMessageComponents parsed = MimeMessageParser.parseMimeMessage(mimeMessage);
final ParsedMimeMessageComponents parsed = MimeMessageParser.parseMimeMessage(mimeMessage, attachmentData);
return decryptAttachments(buildEmailFromMimeMessage(builder, parsed), mimeMessage, pkcs12Config);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,16 @@ public final class MimeMessageParser {
}

/**
* Extracts the content of a MimeMessage recursively.
* Delegates to {@link #parseMimeMessage(MimeMessage, boolean)}.
*/
public static ParsedMimeMessageComponents parseMimeMessage(@NotNull final MimeMessage mimeMessage) {
return parseMimeMessage(mimeMessage, true);
}

/**
* Extracts the content of a MimeMessage recursively.
*/
public static ParsedMimeMessageComponents parseMimeMessage(@NotNull final MimeMessage mimeMessage, boolean attachmentData) {
final ParsedMimeMessageComponents parsedComponents = new ParsedMimeMessageComponents();
parsedComponents.messageId = parseMessageId(mimeMessage);
parsedComponents.sentDate = parseSentDate(mimeMessage);
Expand All @@ -127,12 +134,13 @@ public static ParsedMimeMessageComponents parseMimeMessage(@NotNull final MimeMe
parsedComponents.bccAddresses.addAll(parseBccAddresses(mimeMessage));
parsedComponents.fromAddress = parseFromAddress(mimeMessage);
parsedComponents.replyToAddresses = parseReplyToAddresses(mimeMessage);
parseMimePartTree(mimeMessage, parsedComponents);
parseMimePartTree(mimeMessage, parsedComponents, attachmentData);
moveInvalidEmbeddedResourcesToAttachments(parsedComponents);
return parsedComponents;
}

private static void parseMimePartTree(@NotNull final MimePart currentPart, @NotNull final ParsedMimeMessageComponents parsedComponents) {
private static void parseMimePartTree(@NotNull final MimePart currentPart, @NotNull final ParsedMimeMessageComponents parsedComponents,
boolean attachmentData) {
for (final Header header : retrieveAllHeaders(currentPart)) {
parseHeader(header, parsedComponents);
}
Expand All @@ -149,10 +157,10 @@ private static void parseMimePartTree(@NotNull final MimePart currentPart, @NotN
} else if (isMimeType(currentPart, "multipart/*")) {
final Multipart mp = parseContent(currentPart);
for (int i = 0, count = countBodyParts(mp); i < count; i++) {
parseMimePartTree(getBodyPartAtIndex(mp, i), parsedComponents);
parseMimePartTree(getBodyPartAtIndex(mp, i), parsedComponents, attachmentData);
}
} else {
final DataSource ds = createDataSource(currentPart);
final DataSource ds = createDataSource(currentPart, attachmentData);
// if the diposition is not provided, for now the part should be treated as inline (later non-embedded inline attachments are moved)
if (Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
parsedComponents.attachmentList.add(new SimpleEntry<>(parseResourceNameOrUnnamed(parseContentID(currentPart), parseFileName(currentPart)), ds));
Expand Down Expand Up @@ -373,16 +381,22 @@ public static DataHandler retrieveDataHandler(@NotNull final MimePart part) {
* @return the DataSource
*/
@NotNull
private static DataSource createDataSource(@NotNull final MimePart part) {
private static DataSource createDataSource(@NotNull final MimePart part, boolean attachmentData) {
final DataHandler dataHandler = retrieveDataHandler(part);
final DataSource dataSource = dataHandler.getDataSource();
final String contentType = parseBaseMimeType(dataSource.getContentType());
final byte[] content = readContent(retrieveInputStream(dataSource));
final ByteArrayDataSource result = new ByteArrayDataSource(content, contentType);
final String dataSourceName = parseDataSourceName(part, dataSource);

result.setName(dataSourceName);
return result;
if (attachmentData) {
final String contentType = parseBaseMimeType(dataSource.getContentType());
final byte[] content = readContent(retrieveInputStream(dataSource));
final ByteArrayDataSource result = new ByteArrayDataSource(content, contentType);
final String dataSourceName = parseDataSourceName(part, dataSource);

result.setName(dataSourceName);
return result;
}
else {
return dataSource;
}
}

@SuppressWarnings("WeakerAccess")
Expand Down

0 comments on commit 7ff414a

Please sign in to comment.