Skip to content

Commit

Permalink
#235: Be able to fix the sent date for a new email
Browse files Browse the repository at this point in the history
  • Loading branch information
bbottema committed Nov 17, 2019
1 parent c4bb23b commit dfd6407
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 26 deletions.
2 changes: 1 addition & 1 deletion modules/cli-module/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<dependency>
<groupId>com.github.bbottema</groupId>
<artifactId>java-reflection</artifactId>
<version>3.11.0</version>
<version>3.13.0</version>
</dependency>

<!-- needed for cli support -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -83,6 +84,7 @@ public final class BuilderApiToPicocliCommandsMapper {
put(X509Certificate.class, "PEM FILE");
put(UUID.class, "UUID");
put(LoadBalancingStrategy.class, "NAME");
put(Date.class, "yyyy-[M]M-[d]d[ HH:mm]");
}};

static {
Expand Down Expand Up @@ -139,8 +141,11 @@ private static void generateOptionsFromBuilderApi(Class<?> apiNode, Set<Class<?>
// assertion check
for (CliDeclaredOptionSpec knownOption : cliOptionsFoundSoFar) {
if (knownOption.getName().equals(optionName)) {
String msg = "@CliOptionNameOverride needed one of the following two methods:\n\t%s\n\t%s\n\t----------";
throw new AssertionError(format(msg, knownOption.getSourceMethod(), m));
final boolean methodIsActuallyTheSame = knownOption.getSourceMethod().equals(m);
if (!methodIsActuallyTheSame) {
String msg = "@CliOptionNameOverride needed one of the following two methods:\n\t%s\n\t%s\n\t----------";
throw new AssertionError(format(msg, knownOption.getSourceMethod(), m));
}
}
}

Expand Down
1 change: 1 addition & 0 deletions modules/cli-module/src/test/java/demo/CliDemoApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ private static void demoSend(ServerConfig serverConfig) {
"--email:forwarding", SOURCE_FOLDER + "/test/resources/test-messages/HTML mail with replyto and attachment and embedded image.msg",
"--email:from", "Test sender", DemoAppBase.YOUR_GMAIL_ADDRESS,
"--email:to", "Test Receiver", DemoAppBase.YOUR_GMAIL_ADDRESS,
"--email:fixingSentDate", "2011-5-10 11:15",
"--mailer:withSMTPServer", "smtp.gmail.com", "587", serverConfig.getUsername(), serverConfig.getPassword(),
"--mailer:withTransportStrategy", "SMTP_TLS"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.io.InputStream;
import java.security.cert.X509Certificate;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -189,6 +190,18 @@ public class Email implements Serializable {
@SuppressWarnings("deprecation")
private final boolean wasMergedWithSmimeSignedMessage;

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Nullable
private final Date sentDate;

/**
* @see EmailPopulatingBuilder#getOriginalSentDate()
*/
@Nullable
private final Date originalSentDate;

/**
* Simply transfers everything from {@link EmailPopulatingBuilder} to this Email instance.
*
Expand Down Expand Up @@ -233,6 +246,9 @@ public Email(@NotNull final EmailPopulatingBuilder builder) {

originalSmimeDetails = builder.getOriginalSmimeDetails();

sentDate = builder.getSentDate();
originalSentDate = builder.getOriginalSentDate();

x509CertificateForSmimeEncryption = builder.getX509CertificateForSmimeEncryption();
pkcs12ConfigForSmimeSigning = builder.getPkcs12ConfigForSmimeSigning();

Expand Down Expand Up @@ -310,7 +326,11 @@ public boolean equals(final Object o) {
@Override
public String toString() {
String s = "Email{" +
"\n\tid=" + id +
"\n\tid=" + id;
if (originalSentDate != null) {
s += "\n\toriginalSentDate=" + originalSentDate;
}
s += "\n\tsentDate=" + sentDate +
"\n\tfromRecipient=" + fromRecipient +
",\n\treplyToRecipient=" + replyToRecipient +
",\n\tbounceToRecipient=" + bounceToRecipient +
Expand Down Expand Up @@ -584,4 +604,20 @@ public Email getSmimeSignedEmail() {
public OriginalSmimeDetails getOriginalSmimeDetails() {
return originalSmimeDetails;
}

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Nullable
public Date getSentDate() {
return sentDate;
}

/**
* @see EmailPopulatingBuilder#getOriginalSentDate()
*/
@Nullable
public Date getOriginalSentDate() {
return originalSentDate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.InputStream;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -1163,7 +1164,7 @@ EmailPopulatingBuilder signWithDomainKey(@NotNull InputStream dkimPrivateKeyInpu
*/
@SuppressWarnings("unused")
EmailPopulatingBuilder withReturnReceiptTo(@Nullable String fixedName, @NotNull InternetAddress address);

/**
* Indicates that this email should use the <a href="https://en.wikipedia.org/wiki/Return_receipt">RRT flag "Return-Receipt-To"</a> with the
* preconfigured {@link Recipient}. This flag can be used to request a notification from the SMTP server recipient to signal that the recipient
Expand All @@ -1174,6 +1175,16 @@ EmailPopulatingBuilder signWithDomainKey(@NotNull InputStream dkimPrivateKeyInpu
*/
EmailPopulatingBuilder withReturnReceiptTo(@NotNull Recipient recipient);

/**
* When the an email is sent it is converted to a MimeMessage at which time the sent-date is filled with the current date. With this method
* this can be fixed to a date of choice.
* <p>
* Note that the sent date is never filled by Simple Java Mail, for example when converting from an Outlook or MimeMessage to Email.
*
* @param sentDate The date to use as sent date.
*/
EmailPopulatingBuilder fixingSentDate(@NotNull Date sentDate);

/**
* Resets <em>id</em> to empty.
*/
Expand Down Expand Up @@ -1269,6 +1280,12 @@ EmailPopulatingBuilder signWithDomainKey(@NotNull InputStream dkimPrivateKeyInpu
@SuppressWarnings("unused")
EmailPopulatingBuilder clearReturnReceiptTo();

/**
* Clears the fixed <em>sent-date</em> so that the current date is used again at the time of sending.
*/
@SuppressWarnings("unused")
EmailPopulatingBuilder clearSentDate();

/**
* When readig and converting an email, this flag makes the behavior revert back to the default merging
* behavior for single S/MIME signed attachments, which is that it <em>is</em> merged into the root message.
Expand Down Expand Up @@ -1466,5 +1483,16 @@ EmailPopulatingBuilder signWithDomainKey(@NotNull InputStream dkimPrivateKeyInpu
*/
@Nullable
X509Certificate getX509CertificateForSmimeEncryption();
}

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Nullable
Date getSentDate();

/**
* Contains the original sent-date when converting an existing message to Email. Not used when creating new mails.
*/
@Nullable
Date getOriginalSentDate();
}
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,9 @@ public static String outlookMsgToEML(@NotNull final InputStream outlookMsgInputS
private static EmailPopulatingBuilder buildEmailFromMimeMessage(@NotNull final EmailPopulatingBuilder builder, @NotNull final ParsedMimeMessageComponents parsed) {
checkNonEmptyArgument(builder, "emailBuilder");
checkNonEmptyArgument(parsed, "parsedMimeMessageComponents");
if (parsed.getSentDate() != null) {
((InternalEmailPopulatingBuilder) builder).withOriginalSentDate(parsed.getSentDate());
}
if (parsed.getFromAddress() != null) {
builder.from(parsed.getFromAddress().getPersonal(), parsed.getFromAddress().getAddress());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MimeMessageParseException extends MailException {
static final String ERROR_GETTING_RECIPIENTS = "Error getting [%s] recipient types";
static final String ERROR_GETTING_SUBJECT = "Error getting subject";
static final String ERROR_GETTING_MESSAGE_ID = "Error getting message ID";
static final String ERROR_GETTING_SEND_DATE = "Error getting sent-date";
static final String ERROR_PARSING_REPLY_TO_ADDRESSES = "Error parsing replyTo addresses";

MimeMessageParseException(@NotNull final String message, @Nullable final Exception cause) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -119,6 +120,7 @@ public final class MimeMessageParser {
public static ParsedMimeMessageComponents parseMimeMessage(@NotNull final MimeMessage mimeMessage) {
final ParsedMimeMessageComponents parsedComponents = new ParsedMimeMessageComponents();
parsedComponents.messageId = parseMessageId(mimeMessage);
parsedComponents.sentDate = parseSentDate(mimeMessage);
parsedComponents.subject = parseSubject(mimeMessage);
parsedComponents.toAddresses.addAll(parseToAddresses(mimeMessage));
parsedComponents.ccAddresses.addAll(parseCcAddresses(mimeMessage));
Expand Down Expand Up @@ -515,6 +517,16 @@ public static String parseMessageId(@NotNull final MimeMessage mimeMessage) {
}
}

@SuppressWarnings("WeakerAccess")
@Nullable
public static Date parseSentDate(@NotNull final MimeMessage mimeMessage) {
try {
return mimeMessage.getSentDate();
} catch (final MessagingException e) {
throw new MimeMessageParseException(MimeMessageParseException.ERROR_GETTING_SEND_DATE, e);
}
}

static void moveInvalidEmbeddedResourcesToAttachments(ParsedMimeMessageComponents parsedComponents) {
final String htmlContent = parsedComponents.htmlContent.toString();
for(Iterator<Map.Entry<String, DataSource>> it = parsedComponents.cidMap.entrySet().iterator(); it.hasNext(); ) {
Expand Down Expand Up @@ -546,6 +558,7 @@ public static class ParsedMimeMessageComponents {
final StringBuilder htmlContent = new StringBuilder();
private String calendarMethod;
private String calendarContent;
private Date sentDate;

@Nullable
public String getMessageId() {
Expand Down Expand Up @@ -625,6 +638,11 @@ public String getCalendarContent() {
public String getCalendarMethod() {
return calendarMethod;
}

@Nullable
public Date getSentDate() {
return sentDate;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.simplejavamail.internal.modules.ModuleLoader;

import org.jetbrains.annotations.NotNull;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
Expand All @@ -12,6 +13,7 @@

import static org.simplejavamail.internal.util.MiscUtil.checkArgumentNotEmpty;
import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
import static org.simplejavamail.internal.util.SimpleOptional.ofNullable;

/**
* Helper class that produces and populates a mime messages. Deals with javax.mail RFC MimeMessage stuff, as well as
Expand Down Expand Up @@ -69,7 +71,7 @@ public String toString() {
populateMimeMessageMultipartStructure(message, email);

MimeMessageHelper.setHeaders(email, message);
message.setSentDate(new Date());
message.setSentDate(ofNullable(email.getSentDate()).orElse(new Date()));

/*
The following order is important:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -237,6 +238,18 @@ public class EmailPopulatingBuilderImpl implements InternalEmailPopulatingBuilde
*/
private boolean mergeSingleSMIMESignedAttachment = true;

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Nullable
private Date sentDate;

/**
* @see EmailPopulatingBuilder#getOriginalSentDate()
*/
@Nullable
private Date originalSentDate;

/**
* @see EmailStartingBuilder#startingBlank()
*/
Expand Down Expand Up @@ -313,7 +326,7 @@ private void validateDkim() {
checkNonEmptyArgument(getFromRecipient(), "fromRecipient required when signing DKIM");
}
}

/**
* @see EmailPopulatingBuilder#fixingMessageId(String)
*/
Expand Down Expand Up @@ -1714,6 +1727,25 @@ public InternalEmailPopulatingBuilder withSmimeSignedEmail(@NotNull final Email
return this;
}

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Override
public EmailPopulatingBuilder fixingSentDate(@NotNull final Date sentDate) {
this.sentDate = sentDate;
return this;
}

/**
* @see EmailPopulatingBuilder#getOriginalSentDate()
*/
@Override
@NotNull
public InternalEmailPopulatingBuilder withOriginalSentDate(@NotNull final Date originalSentDate) {
this.originalSentDate = originalSentDate;
return this;
}

/**
* @see EmailPopulatingBuilder#notMergingSingleSMIMESignedAttachment()
*/
Expand Down Expand Up @@ -1863,6 +1895,15 @@ public EmailPopulatingBuilder clearReturnReceiptTo() {
return this;
}

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Override
public EmailPopulatingBuilder clearSentDate() {
this.sentDate = null;
return this;
}

/**
* @see EmailPopulatingBuilder#clearSMIMESignedAttachmentMergingBehavior()
*/
Expand Down Expand Up @@ -2124,4 +2165,22 @@ public Pkcs12Config getPkcs12ConfigForSmimeSigning() {
public X509Certificate getX509CertificateForSmimeEncryption() {
return x509CertificateForSmimeEncryption;
}

/**
* @see EmailPopulatingBuilder#fixingSentDate(Date)
*/
@Override
@Nullable
public Date getSentDate() {
return sentDate;
}

/**
* @see EmailPopulatingBuilder#getOriginalSentDate()
*/
@Override
@Nullable
public Date getOriginalSentDate() {
return originalSentDate;
}
}
Loading

0 comments on commit dfd6407

Please sign in to comment.