Skip to content

Commit

Permalink
#107: Made replying to more robust and added skeleton for forwarding.…
Browse files Browse the repository at this point in the history
… Also improved documentation.
  • Loading branch information
bbottema committed Nov 6, 2017
1 parent 898719c commit a1176a7
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 42 deletions.
97 changes: 87 additions & 10 deletions src/main/java/org/simplejavamail/email/EmailBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
import static org.simplejavamail.internal.util.MiscUtil.defaultTo;
import static org.simplejavamail.internal.util.MiscUtil.extractEmailAddresses;
import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument;
Expand Down Expand Up @@ -308,6 +309,24 @@ public EmailBuilder text(@Nullable final String text) {
return this;
}

/**
* Prepends {@link #text}.
*/
// FIXME add tests
public EmailBuilder prependText(@Nonnull final String text) {
this.text = text + defaultTo(this.text, "");
return this;
}

/**
* Appends {@link #text}.
*/
// FIXME add tests
public EmailBuilder appendText(@Nonnull final String text) {
this.text = defaultTo(this.text, "") + text;
return this;
}

/**
* Sets the {@link #textHTML}.
*/
Expand All @@ -316,6 +335,24 @@ public EmailBuilder textHTML(@Nullable final String textHTML) {
return this;
}

/**
* Prepends {@link #textHTML}.
*/
// FIXME add tests
public EmailBuilder prependTextHTML(@Nonnull final String textHTML) {
this.textHTML = textHTML + defaultTo(this.textHTML, "");
return this;
}

/**
* Appends {@link #textHTML}.
*/
// FIXME add tests
public EmailBuilder appendTextHTML(@Nonnull final String textHTML) {
this.textHTML = defaultTo(this.textHTML, "") + textHTML;
return this;
}

/**
* Adds new {@link Recipient} instances to the list on account of name, address with recipient type {@link Message.RecipientType#TO}.
*
Expand Down Expand Up @@ -708,32 +745,72 @@ public EmailBuilder asReplyTo(@Nonnull final Email email, boolean repyToAll) {
/**
* Delegates to {@link #asReplyTo(MimeMessage, boolean)} with replyToAll set to <code>true</code>.
*/
public EmailBuilder asReplyTo(MimeMessage email) {
public EmailBuilder asReplyTo(@Nonnull MimeMessage email) {
return asReplyTo(email, true);
}

/**
* Primes the email with all subject, headers and recipients needed for a valid RFC reply.
* <p>
* Note: replaces subject.
* <strong>Note:</strong> replaces subject and body (text replaced with "> text" and HTML
* replaced {@code <blockquote>} if provided).
*
* @see <a href="https://javaee.github.io/javamail/FAQ#reply">Official JavaMail FAQ on replying</a>
* @see javax.mail.internet.MimeMessage#reply(boolean)
*/
public EmailBuilder asReplyTo(MimeMessage emailMessage, boolean repyToAll) {
final Email reply;
public EmailBuilder asReplyTo(@Nonnull MimeMessage emailMessage, boolean repyToAll) {
try {
MimeMessage replyMessage = (MimeMessage) emailMessage.reply(repyToAll);
final MimeMessage replyMessage = (MimeMessage) emailMessage.reply(repyToAll);
replyMessage.setText("ignore");
replyMessage.setFrom("[email protected]");
reply = EmailConverter.mimeMessageToEmail(replyMessage);

final Email original = EmailConverter.mimeMessageToEmail(emailMessage);
final Email generatedReply = EmailConverter.mimeMessageToEmail(replyMessage);

return this
.subject(generatedReply.getSubject())
.to(generatedReply.getRecipients())
.text(valueNullOrEmpty(original.getText()) ? null : original.getText().replaceAll("(?m)^", "> "))
.textHTML(valueNullOrEmpty(original.getTextHTML()) ? null : "<blockquote>" + original.getTextHTML() + "</blockquote>")
.withHeaders(generatedReply.getHeaders());
} catch (MessagingException e) {
throw new EmailException("was unable to parse mimemessage to produce a reply for", e);
}
}

/**
* Delegates to {@link #asForwardOf(MimeMessage, boolean)} with inline set to <code>true</code>.
*/
public EmailBuilder asForwardOf(@Nonnull final Email email) {
return asForwardOf(EmailConverter.emailToMimeMessage(email), true);
}

/**
* Delegates to {@link #asForwardOf(MimeMessage, boolean)}.
*/
public EmailBuilder asForwardOf(@Nonnull final Email email, boolean inline) {
return asForwardOf(EmailConverter.emailToMimeMessage(email), inline);
}

/**
* Delegates to {@link #asForwardOf(MimeMessage, boolean)} with inline set to <code>true</code>.
*/
public EmailBuilder asForwardOf(@Nonnull MimeMessage email) {
return asForwardOf(email, true);
}

/**
* Primes the email with all subject, headers needed for a valid RFC forward.
* <p>
* Note: replaces subject.
*
* @param inline Indicates whether to include the original body as inline content on the new body or as attachment
* @see <a href="https://javaee.github.io/javamail/FAQ#forward">Official JavaMail FAQ on forwarding</a>
*/
public EmailBuilder asForwardOf(@Nonnull MimeMessage emailMessage, final boolean inline) {

return this
.subject(reply.getSubject())
.to(reply.getRecipients())
.withHeaders(reply.getHeaders());

return this;
}

/*
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/simplejavamail/internal/util/MiscUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,9 @@ public static String[] extractEmailAddresses(@Nonnull final String emailAddressL
.replaceAll("<\\|>$", "") // remove trailing delimiter
.split("\\s*<\\|>\\s*"); // split on delimiter including surround space
}

@Nullable
public static <T> T defaultTo(@Nullable T value, @Nullable T defaultValue) {
return value != null ? value : defaultValue;
}
}
115 changes: 83 additions & 32 deletions src/main/webapp/src/app/components/features/features.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ <h1>Simple Java Mail Features</h1>
email addresses against <a href="https://tools.ietf.org/html/rfc2822">RFC-2822</a> using the only complete <a
href="https://github.com/bbottema/email-rfc2822-validator">rfc2822 validator in java</a> in the world.
</p>

<p class="wide">
Simple Java Mail also takes care of all the
<a href="https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html">connection and security properties</a> for you.
</p>
</section>

<section class="toc">
Expand All @@ -37,8 +42,9 @@ <h1>Simple Java Mail Features</h1>
<li><a simplePageScroll href="#section-return-receipt">Configure delivery / read receipt</a></li>
<li><a simplePageScroll href="#section-email-validation">Validating Email Addresses</a></li>
<li><a simplePageScroll href="#section-converting">Converting between email formats</a></li>
<li><a simplePageScroll href="#section-proxy">Send using a proxy</a></li>
<li><a simplePageScroll href="#section-bouncing-emails">Setting custom recipient for bouncing emails</a></li>
<li><a simplePageScroll href="#section-reply-forward">Replying to and forwarding emails</a></li>
<li><a simplePageScroll href="#section-proxy">Send using a proxy</a></li>
</ul>
</section>

Expand Down Expand Up @@ -570,6 +576,82 @@ <h2>Converting between, Email, MimeMessage, EML and Outlook .msg</h2>
</section>


<a href="#section-bouncing-emails" id="section-bouncing-emails" class="section-link h2">&sect;</a>
<h2>Setting custom recipient for bouncing emails</h2>

<section>
<div class="view">
<p>
For bouncing emails, you can provide a hint to the SMTP server to which bouncing emails should be returned.
This is also known as the Return-Path or Envelope FROM and is set on the Session instance with the property
<code class="inline">mail.smtp.from</code>.
</p>
<p>
Simple Java Mail offers a convenience method to set this property.
</p>
</div>

<div class="side">
<pre><code>
// in similar fashion to setting replyTo address:
email.setBounceToRecipient(aRecipientInstance); // or
email.setBounceToAddress("Bob", "[email protected]");

// Or using the Builder:
Email email = new EmailBuilder()
.bounceTo(aRecipientInstance) // or
.bounceTo("Bob", "[email protected]")
.build();
</code></pre>
</div>
</section>


<a href="#section-reply-forward" id="section-reply-forward" class="section-link h2">&sect;</a>
<h2>Replying to and forwarding emails</h2>

<section>
<div class="view">
<p>
If you have an email you want to reply to or wish to forward, the <code class="inline">EmailBuilder</code>
has you covered.
</p>
<br />
<div>
<p>
<strong>Note:</strong> due to the nature of the underlying JavaMail framework (also see
<a href="https://javaee.github.io/javamail/FAQ#reply">reply</a> /
<a href="https://javaee.github.io/javamail/FAQ#forward">forward</a>):
</p>
<ul class="indent">
<li>In case of replying, the original email is quoted in the body of the reply itself.</li>
<li>In case of forwarding, the original email is included as a separate body inside the forward.</li>
</ul>
</div>
</div>

<div class="side">
<p>Replying to an email:</p>
<pre><code>
Email reply = new EmailBuilder()
.asReplyTo(receivedEmail) // Email or MimeMessage
.from("[email protected]")
.prependText("Reply body. Original email included below")
.build();
</code></pre>
<p>Forwarding an email:</p>
<pre><code>
// forwarding an email
Email reply = new EmailBuilder()
.asForwardOf(receivedEmail) // Email or MimeMessage
.from("[email protected]")
.text("Hello? This is Forward. See below email:")
.build();
</code></pre>
</div>
</section>


<a href="#section-proxy" id="section-proxy" class="section-link h2">&sect;</a>
<h2>Send using a proxy</h2>

Expand Down Expand Up @@ -603,36 +685,5 @@ <h2>Send using a proxy</h2>
on how to set proxy server defaults and the port on which the proxy bridge runs.</p>
</div>
</section>


<a href="#section-bouncing-emails" id="section-bouncing-emails" class="section-link h2">&sect;</a>
<h2>Setting custom recipient for bouncing emails</h2>

<section>
<div class="view">
<p>
For bouncing emails, you can provide a hint to the SMTP server to which bouncing emails should be returned.
This is also known as the Return-Path or Envelope FROM and is set on the Session instance with the property
<code class="inline">mail.smtp.from</code>.
</p>
<p>
Simple Java Mail offers a convenience method to set this property.
</p>
</div>

<div class="side">
<pre><code>
// in similar fashion to setting replyTo address:
email.setBounceToRecipient(aRecipientInstance); // or
email.setBounceToAddress("Bob", "[email protected]");

// Or using the Builder:
Email email = new EmailBuilder()
.bounceTo(aRecipientInstance) // or
.bounceTo("Bob", "[email protected]")
.build();
</code></pre>
</div>
</section>

</div>

0 comments on commit a1176a7

Please sign in to comment.