org.simplejavamail.converter.internal.mimemessage.SpecializedMimeMessageProducer Maven / Gradle / Ivy
Show all versions of simple-java-mail Show documentation
/*
* Copyright © 2009 Benny Bottema ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.simplejavamail.converter.internal.mimemessage;
import jakarta.mail.MessagingException;
import jakarta.mail.Session;
import jakarta.mail.internet.MimeMessage;
import org.jetbrains.annotations.NotNull;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.internal.moduleloader.ModuleLoader;
import org.simplejavamail.mailer.internal.util.MessageIdFixingMimeMessage;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import static java.util.Optional.ofNullable;
import static org.simplejavamail.internal.util.MiscUtil.checkArgumentNotEmpty;
import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument;
/**
* Helper class that produces and populates a mime messages. Deals with jakarta.mail RFC MimeMessage stuff, as well as
* DKIM signing and
* S/MIME signing / encryption.
*
* Some more helpful reading
* material.
*
* One goal of these classes is to produce a Mime structure that exactly matches the email's need. Previously, Simple Java Mail
* used a complex RFC-conforming structure that is compatible with all situations, but it seems
* some email clients would still get confused.
* Due to this, we explicitely define all possible structures so we take the least complex one needed.
*
* @see #144: Simple Java Mail should tailor the MimeMessage structure to specific needs
*/
public abstract class SpecializedMimeMessageProducer {
/**
* @return Whether this mimemessage producer exactly matches the needs of the given email.
*/
abstract boolean compatibleWithEmail(@NotNull Email email);
final MimeMessage populateMimeMessage(@NotNull final Email email, @NotNull Session session)
throws MessagingException, UnsupportedEncodingException {
checkArgumentNotEmpty(email, "email is missing");
checkArgumentNotEmpty(session, "session is needed, it cannot be attached later");
MimeMessage message = new MessageIdFixingMimeMessage(session, email.getId());
// set basic email properties
MimeMessageHelper.setSubject(email, message);
MimeMessageHelper.setFrom(email, message);
MimeMessageHelper.setReplyTo(email, message);
MimeMessageHelper.setRecipients(email, message);
populateMimeMessageMultipartStructure(message, email);
MimeMessageHelper.setHeaders(email, message);
message.setSentDate(ofNullable(email.getSentDate()).orElse(new Date()));
/*
The following order is important:
1. S/MIME signing
2. S/MIME encryption
3. DKIM signing
*/
if (email.getSmimeSigningConfig() != null) {
message = ModuleLoader.loadSmimeModule().signMessageWithSmime(session, email, message, email.getSmimeSigningConfig());
}
if (email.getSmimeEncryptionConfig() != null) {
message = ModuleLoader.loadSmimeModule().encryptMessageWithSmime(session, email, message, email.getSmimeEncryptionConfig());
}
if (email.getDkimConfig() != null) {
message = ModuleLoader.loadDKIMModule().signMessageWithDKIM(email, message, email.getDkimConfig(), checkNonEmptyArgument(email.getFromRecipient(), "fromRecipient"));
}
if (email.getBounceToRecipient() != null) {
// display name not applicable: https://tools.ietf.org/html/rfc5321#section-4.1.2
message = new ImmutableDelegatingSMTPMessage(message, email.getBounceToRecipient().getAddress());
}
return message;
}
abstract void populateMimeMessageMultipartStructure(MimeMessage message, Email email) throws MessagingException;
static boolean emailContainsMixedContent(@NotNull Email email) {
return !email.getAttachments().isEmpty() || email.getEmailToForward() != null;
}
static boolean emailContainsRelatedContent(@NotNull Email email) {
return !email.getEmbeddedImages().isEmpty();
}
static boolean emailContainsAlternativeContent(@NotNull Email email) {
return (email.getPlainText() != null ? 1 : 0) +
(email.getHTMLText() != null ? 1 : 0) +
(email.getCalendarText() != null ? 1 : 0) > 1;
}
}